Sono consapevole che ogni oggetto richiede memoria heap e ogni primitiva / riferimento nello stack richiede memoria stack.
Quando provo a creare un oggetto nell'heap e non c'è memoria sufficiente per farlo, la JVM crea un java.lang.OutOfMemoryError sull'heap e me lo lancia.
Quindi implicitamente, ciò significa che c'è un po 'di memoria riservata da JVM all'avvio.
Cosa succede quando questa memoria riservata è esaurita (sarebbe sicuramente esaurita, leggi la discussione sotto) e la JVM non ha abbastanza memoria sull'heap per creare un'istanza di java.lang.OutOfMemoryError ?
Si blocca e basta? O mi lancerebbe un null
dato che non c'è memoria per new
un'istanza di 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
}
==
Perché la JVM non ha potuto riservare memoria sufficiente?
Indipendentemente dalla quantità di memoria riservata, è comunque possibile che quella memoria venga utilizzata se la JVM non ha un modo per "recuperare" quella memoria:
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
}
}
}
}
}
}
O più concisamente:
private void OnOOM(java.lang.OutOfMemoryError e) {
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e2) {
OnOOM(e2);
}
}
OutOfMemoryException
e poi fare qualcosa che comportava la creazione di un grosso buffer ...
OutOfMemoryError
e conservasse un riferimento ad esso. Traspare che catturare un OutOfMemoryError
non sia così utile come si potrebbe pensare, perché non si può garantire quasi nulla sullo stato del programma nel catturarlo. Vedi stackoverflow.com/questions/8728866/…