У цій статті ми розберемо помилки, які можуть виникати в JVM пам'яті.
Пам'ять JVM складається з Heap і Stack областей.
Heap memory — область пам'яті, в якій зберігаються Java об'єкти.
Stack memory — тимчасова область пам'яті, в якій зберігаються примітивні змінні і посилання на об'єкти методу.
java.lang.OutOfMemoryError
Коли в JVM виникають проблеми з HEAP пам'яттю, виникає помилка java.lang.OutOfMemoryError. Крім того, помилка містить повідомлення, яке допоможе нам краще зрозуміти проблему.
Приклад:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Java heap space
Помилка сталася при спробі створення об'єкта, JVM не змогла виділити область пам'яті для нового об'єкта.
GC Overhead limit exceeded
Збирач сміття в JVM витрачає занадто багато часу на складання сміття. Помилка виникає, коли збирач сміття витрачає 98% часу на складання сміття, але при цьому звільняється менше 2% відсотків пам'яті.
public class OutOfMemoryErrorDemo {
public static void main(String[] args) {
int i = 0;
List<String> stringList = new ArrayList<>();
while (i < Integer.MAX_VALUE) {
i++;
String generatedString = new String( "some string generate to show out of memory error demo " + i);
stringList.add(generatedString);
}
}
}
stringList містить посилання на рядки, які ми створюємо, і саме тому збирач сміття не може видалити їх. Це призводить до того, що збирач сміття витрачає багато часу на пошук об'єктів для видалення.
Для відтворення цієї помилки обмежте пам'ять JVM вручну за допомогою параметрів -Xms і -Xmx
Requested array size exceeds VM limit
Виникає, коли ми намагаємося створити масив, який вимагає більше пам'яті, ніж є в HEAP.
public class OutOfMemoryErrorDemo {
public static void main(String[] args) {
// we try to create too long array
long[] array = new long[Integer.MAX_VALUE];
}
Metaspace
Виникає, коли JVM не може виділити пам'ять для зберігання інформації про класи.
request size bytes for reason. Out of swap space?
Виникає, коли в native heap не вистачає пам'яті або вона скоро закінчиться.
reason stack_trace_with_native_method
Ця помилка виникає, коли JVM не вдалося виділити пам'ять для JNI або нативних методів в heap.
StackOverFlowError
З'являється, коли стек JVM переповнений. Найчастіше виникає через нескінченну рекурсію.
public class StackOverFlowErrorDemo {
public static void main(String[] args) {
recursiveMethod(2);
}
public static int recursiveMethod(int i) {
// it will never stop and it allocates all stack memory
return recursiveMethod(i);
}
}