Укр
Ошибки, которые возникают в JVM памяти

Ошибки, которые возникают в JVM памяти

  • 27 сентября, 2021
  • читать 3 мин
Али Жагпаров
Али Жагпаров Java Software Engineer в Devexperts

В этой статье мы разберем ошибки, которые могут возникать в JVM памяти.

Память JVM состоит из Heap и Stack областей.

Heap memory — область памяти, в которой хранятся Java объекты.

Stack memory — временная область памяти, в которой хранятся примитивные переменные и ссылки на объекты метода.

java.lang.OutOfMemoryError

Когда в JVM возникают проблемы с HEAP памятью, возникает ошибка java.lang.OutOfMemoryError. Кроме того, ошибка cодержит сообщение, которое поможет нам лучше понять проблему.

Пример:

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);
   }
}