Ошибка памяти Java Heap

JavaBeginner
Практиковаться сейчас

Введение

В этом лабе вы научитесь эффективно использовать память Java Heap, чтобы избежать ошибок связанных с памятью Java Heap.

Ошибка памяти Java Heap

Ошибка памяти Java Heap возникает, когда виртуальная машина Java (JVM) не может выделить память для объектов в памяти Java Heap. Плохие практики программирования, утечки памяти, сторонние библиотеки могут привести к этой ошибке.

Код:

import java.util.ArrayList;

public class JavaHeapMemoryError {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        while (true) {
            Object o = new Object();
            list.add(o);
        }
    }
}

Для того, чтобы увидеть ошибку в действии, скомпилируйте и запустите код в терминале:

javac JavaHeapMemoryError.java
java -Xmx512m JavaHeapMemoryError

Программа пытается выделить как можно больше памяти, непрерывно создавая объекты и добавляя их в ArrayList, пока JVM не выбросит ошибку OutOfMemoryError. Параметр -Xmx задает максимальный объем памяти, выделяемой JVM.

Причины ошибки памяти Java Heap

Ошибка памяти Java Heap возникает в основном из-за плохих практик программирования, утечки памяти и сторонних библиотек. Чтобы предотвратить ее, мы должны избегать бесконечных циклов, объектов, которые долго хранятся без использования и не очищаются, и предоставлять неиспользуемые объекты сборщику мусора.

Код:

public class JavaHeapMemoryError {
    public static void main(String[] args) {
        int[] arr = new int[100000000];
        for(int i=0; i<arr.length; i++){
            arr[i] = i;
        }
        System.out.println("Memory allocated");
    }
}

Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:

javac JavaHeapMemoryError.java
java -Xmx256m JavaHeapMemoryError

Утечка памяти

Утечка памяти возникает, когда неиспользуемый объект в памяти кучи по-прежнему имеет действительные ссылки и не может быть удален сборщиком мусора. Чтобы избежать утечек памяти, все открытые ресурсы должны быть закрыты с использованием блока finally.

Код:

public class MemoryLeak {
    static ArrayList<String> arrList = new ArrayList<String>(500);
    public static void main(String args[]) {
        for (int i = 0; i < 500; i++) {
            arrList.add("Element " + i);
        }
        arrList = null;
    }
}

Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:

javac MemoryLeak.java
java -Xmx256m MemoryLeak

Превышенное использование финализаторов

Превышенное использование финализаторов может привести к ошибке памяти Java Heap, потому что классы, содержащие метод finalize, не имеют своих пространств объектов, освобождаемых в процессе сборки мусора.

Код:

public class ExcessiveFinalizer {
    public void finalize() {
        //Do some cleanup
    }

    public static void main(String[] args) {
        ArrayList<ExcessiveFinalizer> list = new ArrayList<ExcessiveFinalizer>();
        while (true) {
            list.add(new ExcessiveFinalizer());
        }
    }
}

Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:

javac ExcessiveFinalizer.java
java -Xmx256m ExcessiveFinalizer

Увеличить память Java Heap

Если ошибка была вызвана недостаточностью выделенной для JVM памяти, мы можем увеличить доступное пространство памяти кучи, увеличив предел, установленный командой -Xmx.

Код:

public class IncreaseHeapMemory {
    public static void main(String[] args) {
        Integer[] outOfMemoryArray = new Integer[Integer.MAX_VALUE];
    }
}

Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:

javac IncreaseHeapMemory.java
java -Xmx8g IncreaseHeapMemory

Резюме

В этом практическом занятии вы узнали, как эффективно управлять памятью кучи для ваших Java-приложений, чтобы избежать ошибок памяти Java Heap. Мы изучили различные методы предотвращения ошибок, такие как избегание неэффективных циклов, закрытие неиспользуемых ресурсов и предоставление неиспользуемых объектов сборщику мусора пораньше. Наконец, если недостаточность памяти кучи была причиной ошибки, мы увеличили предел с использованием команды -Xmx.