Java 힙 메모리 오류

JavaBeginner
지금 연습하기

소개

이 랩에서는 Java Heap Memory 오류를 방지하기 위해 Java Heap Memory 를 효과적으로 사용하는 방법을 배웁니다.

Java 힙 메모리 오류

Java Heap Memory 오류는 Java Virtual Machine (JVM) 이 Java Heap Memory 에 객체를 할당하는 동안 메모리가 부족해질 때 발생합니다. 잘못된 프로그래밍 방식, 메모리 누수, 타사 라이브러리 등이 이 오류를 유발할 수 있습니다.

코드:

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 힙 메모리 오류의 원인

Java Heap Memory 오류는 주로 잘못된 프로그래밍 방식, 메모리 누수 및 타사 라이브러리로 인해 발생합니다. 이를 방지하려면 무한 루프를 피하고, 정리되지 않은 채 너무 오래 유지되는 사용하지 않는 객체를 피하며, 사용하지 않는 객체를 가비지 컬렉터 (garbage collector) 에서 사용할 수 있도록 해야 합니다.

코드:

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

메모리 누수

메모리 누수는 힙 메모리 (heap memory) 의 사용하지 않는 객체가 여전히 유효한 참조를 가지고 있어 가비지 컬렉터 (Garbage Collector) 에 의해 제거될 수 없을 때 발생합니다. 메모리 누수를 방지하려면 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

finalizer 과도한 사용

finalizer 의 과도한 사용은 Java Heap Memory 오류로 이어질 수 있습니다. finalize 메서드를 포함하는 클래스는 가비지 컬렉션 (Garbage Collection) 중에 객체 공간이 회수되지 않기 때문입니다.

코드:

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

힙 메모리 증가

오류가 JVM 에 할당된 메모리 부족으로 인해 발생한 경우, -Xmx 명령으로 설정된 제한을 늘려 JVM 에 사용 가능한 힙 공간을 늘릴 수 있습니다.

코드:

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

코드를 실제로 확인하려면 터미널에서 코드를 컴파일하고 실행하십시오.

javac IncreaseHeapMemory.java
java -Xmx8g IncreaseHeapMemory

요약

이 랩에서는 Java Heap Memory 오류를 방지하기 위해 Java 애플리케이션의 힙 메모리를 효과적으로 관리하는 방법을 배웠습니다. 비효율적인 루프를 피하고, 사용하지 않는 리소스를 닫고, 가비지 컬렉터가 사용하지 않는 객체를 조기에 사용할 수 있도록 하는 등 오류를 방지하기 위한 다양한 기술을 살펴보았습니다. 마지막으로, 오류의 원인이 힙 메모리 부족인 경우, -Xmx 명령을 사용하여 제한을 늘렸습니다.