Estou ciente de que todo objeto requer memória de pilha e toda referência / primitivo na pilha requer memória de pilha.
Quando tento criar um objeto no heap e não há memória suficiente para fazer isso, a JVM cria um java.lang.OutOfMemoryError no heap e o lança para mim.
Então, implicitamente, isso significa que há alguma memória reservada pela JVM na inicialização.
O que acontece quando essa memória reservada é usada (definitivamente seria usada, leia a discussão abaixo) e a JVM não possui memória suficiente no heap para criar uma instância de java.lang.OutOfMemoryError ?
Isso apenas trava? Ou ele me daria uma null
vez que não há memória para new
uma instância do OOM?
try {
Object o = new Object();
// and operations which require memory (well.. that's like everything)
} catch (java.lang.OutOfMemoryError e) {
// JVM had insufficient memory to create an instance of java.lang.OutOfMemoryError to throw to us
// what next? hangs here, stuck forever?
// or would the machine decide to throw us a "null" ? (since it doesn't have memory to throw us anything more useful than a null)
e.printStackTrace(); // e.printStackTrace() requires memory too.. =X
}
==
Por que a JVM não pôde reservar memória suficiente?
Independentemente da quantidade de memória reservada, ainda é possível que essa memória seja usada se a JVM não tiver uma maneira de "recuperar" essa memória:
try {
Object o = new Object();
} catch (java.lang.OutOfMemoryError e) {
// JVM had 100 units of "spare memory". 1 is used to create this OOM.
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e2) {
// JVM had 99 units of "spare memory". 1 is used to create this OOM.
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e3) {
// JVM had 98 units of "spare memory". 1 is used to create this OOM.
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e4) {
// JVM had 97 units of "spare memory". 1 is used to create this OOM.
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e5) {
// JVM had 96 units of "spare memory". 1 is used to create this OOM.
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e6) {
// JVM had 95 units of "spare memory". 1 is used to create this OOM.
e.printStackTrace();
//........the JVM can't have infinite reserved memory, he's going to run out in the end
}
}
}
}
}
}
Ou, mais concisamente:
private void OnOOM(java.lang.OutOfMemoryError e) {
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e2) {
OnOOM(e2);
}
}
OutOfMemoryException
e, em seguida, fazer algo que envolveu a criação de um buffer grande ...
OutOfMemoryError
e mantivesse uma referência a ela. Parece que pegar um OutOfMemoryError
não é tão útil quanto se poderia pensar, porque você pode garantir quase nada sobre o estado do seu programa ao pegá-lo. Veja stackoverflow.com/questions/8728866/…