Catch de Error

Com try/ catch eu posso pegar qualquer objeto Throwable.
Error é uma classe que extende Throwable.

Faz sentido tratar Erros (da mesma forma que tratamos Exceptions)?

Eu identifiquei uma situação: uma função recursiva que pode consumir todos os recursos da maquina:

[code]public class A{

    public void doIt(){ doIt(); }

    public static void main(String [] args){
            A a = new A();
            try{
                    a.doIt();
            }catch(Error e){
                    System.out.println("Error: " + e);
            }
            System.out.println("fim");
    }

}[/code]

Agora… existem outras situações?

Olá!

Possível é possível, como você mesmo disse ao afirmar que Error extende Trowable, mas se for pela lógica não faz sentido capturar um Error, pois quando um desses é lançado a JVM é encerrada… nem chega no catch…

Abraços

Chega no catch sim. Você pode não impedir que a VM aborte, mas você pode gravar num arquivo a causa do erro, antes disso.

Mas geralmente, é mais útil registrar o defaultUncaughtExceptionHandler para isso.

Dê uma olhada na classe Thread e no método setDefaultUncaughtExceptionHandler. É o método que é chamado quando um throwable não é capturado por classe nenhuma, antes da VM abortar. É útil para logar eventuais erros e runtimeexceptions num arquivo, antes do programa cair fora.

Existe também o setUncaughtExceptionHandler, que não é estático, caso você queira registrar um handler diferente para uma thread específica.

Olá!

:smiley:

Eu sempre achei que nem chegava no catch quando um Error é lançado… mas parece ser bem útil nesse seu exemplo…

Abraços

[quote=ViniGodoy]Chega no catch sim. Você pode não impedir que a VM aborte, mas você pode gravar num arquivo a causa do erro, antes disso.

Mas geralmente, é mais útil registrar o defaultUncaughtExceptionHandler para isso.

Dê uma olhada na classe Thread e no método setDefaultUncaughtExceptionHandler. É o método que é chamado quando um throwable não é capturado por classe nenhuma, antes da VM abortar. É útil para logar eventuais erros e runtimeexceptions num arquivo, antes do programa cair fora.

Existe também o setUncaughtExceptionHandler, que não é estático, caso você queira registrar um handler diferente para uma thread específica.[/quote]

Vini, mas como eu posso ter garantia de que dependendo do Error, a JVM vai conseguir tratar?? Eu poderia ter um erro que fizesse ela para de forma brusca antes dela chegar no catch??

Att

Realmente, não há garantias, especialmente em erros de JNI, por exemplo.

Mas erros de coisas que estão sobre o controle da VM como OutOfMemory, AWTError, StackOverflowError, ThreadDeath são capturados, o que já aumenta muito o grau de confiabilidade dos seus traces.

É bom lembrar que um OutOfMemory representa falta de memória do programa, não do PC ou da VM. O mesmo vale par ao StackOverflow. Por isso, é relativamente fácil para VM captura-los. :slight_smile:

[quote=ViniGodoy]Realmente, não há garantias, especialmente em erros de JNI, por exemplo.

Mas erros de coisas que estão sobre o controle da VM como OutOfMemory, AWTError, StackOverflowError, ThreadDeath são capturados, o que já aumenta muito o grau de confiabilidade dos seus traces.

É bom lembrar que um OutOfMemory representa falta de memória do programa, não do PC ou da VM. O mesmo vale par ao StackOverflow. Por isso, é relativamente fácil para VM captura-los. :)[/quote]

Vini, desculpa minha ignorância, mas como memória do “programa”, a medida que vou precisando de memória eu vou alocando mais, até chegar a hora que acaba a memória da VM não??

Me explica melhor!

Att

Até acabar a memória da VM, não do SO. Quando a VM sobe, ela pré aloca um espaço para o heap. Esse espaço é dobrado até atingir o limite máximo, que por padrão é, se eu não me engano, míseros 64MB. Esse é o espaço máximo em que se pode alocar usando new (variáveis locais sem new não contam, já que ficam no stack).

É para isso que serve o parâmetro -Xmx, ele permite que você aumente o tamanho do Heap. Applications servers já tem esse parâmetro configurado para valores bem maiores.

O parâmetro -Xms serve para definir qual é o tamanho inicial que o heap da VM irá ocupar (é por isso que um programa Java já consome um caminhão de memória logo que sobe).

A mesma coisa acontece com o StackOverflowError. Existem outros parâmetros na VM que permitem configurar o tamanho exato dos stacks e, se você tiver um programa muito recursivo (ou que esteja rodando num hardware mais limitado), você pode ajustar esses valores.

Por isso os erros podem ser capturados pela VM, já que ela pode deixar sua aplicação sem recursos, mas ela mesmo não estar sem recursos do SO.

Alguns bons artigos sobre esse assunto:
HotSpot Engine Architecture
HotSpot Ergonomics
HotSpot VM Command Line Options
Java Performance FAQ
Tuning Garbage Collection with the 5.0 Java Virtual Machine
HotSpot Class Data Sharing
Big Heaps and Intimate Shared Memory (ISM)
J2SE 5.0 Performance White Paper