Я знаю, что каждый объект требует кучи памяти, и каждый примитив / ссылка в стеке требует стековой памяти.
Когда я пытаюсь создать объект в куче, и для этого недостаточно памяти, JVM создает в куче java.lang.OutOfMemoryError и выдает его мне.
Таким образом, это неявно означает, что JVM зарезервировала некоторую память при запуске.
Что происходит, когда эта зарезервированная память израсходована (она, безусловно, будет израсходована, см. Обсуждение ниже), а JVM не хватает памяти в куче для создания экземпляра java.lang.OutOfMemoryError ?
Это просто висит? Или он бросит мне, null
так как нет памяти для new
экземпляра 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
}
==
Почему JVM не может зарезервировать достаточно памяти?
Независимо от того, сколько памяти зарезервировано, эта память все еще может быть использована, если у JVM нет способа «восстановить» эту память:
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
}
}
}
}
}
}
Или более кратко:
private void OnOOM(java.lang.OutOfMemoryError e) {
try {
e.printStackTrace();
} catch (java.lang.OutOfMemoryError e2) {
OnOOM(e2);
}
}
OutOfMemoryException
а затем сделать что-то, что включало создание большого буфера ...
OutOfMemoryError
и сохранит ссылку на нее. Выясняется, что перехват OutOfMemoryError
не так полезен, как можно подумать, потому что вы почти ничего не можете гарантировать о состоянии вашей программы при перехвате. См stackoverflow.com/questions/8728866/...