[java] java.lang.OutOfMemoryError : Java 힙 공간

멀티 스레딩 프로그램 실행시 다음과 같은 오류가 발생합니다.

java.lang.OutOfMemoryError: Java heap space

위의 오류는 스레드 중 하나에서 발생했습니다.

  1. 내가 아는 한 힙 공간은 인스턴스 변수로만 차지합니다. 이것이 맞다면, 객체 생성시 인스턴스 변수를위한 공간이 할당 되었기 때문에 얼마 동안 잘 실행 된 후이 오류가 발생한 이유입니다.

  2. 힙 공간을 늘리는 방법이 있습니까?

  3. 힙 공간을 덜 차지하려면 프로그램을 어떻게 변경해야합니까?



답변

힙 공간을 늘리려면 java -Xms<initial heap size> -Xmx<maximum heap size>명령 줄에서 사용할 수 있습니다 . 기본적으로 값은 JRE 버전 및 시스템 구성을 기반으로합니다. Java 웹 사이트에서 VM 옵션에 대해 자세히 알아볼 수 있습니다 .

그러나 애플리케이션을 프로파일 링하여 힙 크기가 소비되는 이유를 알아내는 것이 좋습니다. NetBeans에는 매우 우수한 프로파일 러가 포함되어 있습니다. 나는 그것이 jvisualvm후드 아래를 사용한다고 믿습니다 . 프로파일 러를 사용하면 많은 개체가 생성되는 위치, 개체가 가비지 수집되는시기 등을 찾을 수 있습니다.


답변

1.- 예,하지만 프로그램에서 사용하는 전체 메모리를 의미합니다.

2.- 예, Java VM 옵션 참조

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

java -Xmx2g 앱에 최대 2GB의 램 할당

그러나 먼저 메모리 누수가 없는지 확인해야합니다.

3.- 프로그램에 따라 다릅니다. 스팟 메모리 누수를 시도하십시오. 이 질문은 대답하기 어려울 것입니다. 최근에는 JConsole을 사용하여 프로필을 작성하여 메모리가 어디로 가는지 알아낼 수 있습니다.


답변

JVM의 메모리에 대해 자세히 알아 보려면이 사이트를 참조하십시오 .
http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

Visualgc 를 사용 하여 메모리 모델의 다른 부분이 어떻게 채워지는지보고 무엇을 변경할지 결정하는 것이 유용하다는 것을 알았 습니다.

메모리의 어느 부분이 채워 졌는지 확인하는 것은 어렵습니다. 따라서 visualgc는 다음과 같이 말하지 않고 문제가있는 부분 만 변경하고자 할 수 있습니다.

좋아! JVM에 1G의 RAM을 줄 것입니다.

당신이하고있는 일에 대해 더 정확하게하려고 노력하십시오. 장기적으로 당신은 아마도 프로그램이 더 나은 것을 발견 할 것입니다.

메모리 누수가 어디에 있는지 확인하려면 테스트 전과 후에 메모리가 무엇인지 테스트하여 단위 테스트를 사용할 수 있습니다. 변경 사항이 너무 크면 검사해야 할 수도 있지만 테스트가 계속 실행되는 동안 확인하십시오.


답변

힙 크기를 늘리려면 Java를 시작할 때 -Xmx 인수를 사용할 수 있습니다. 예 :

-Xmx256M


답변

아래 프로그램을 통해 힙 메모리 크기를 얻을 수 있습니다.

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

따라서 다음을 사용하여 힙 크기를 늘릴 수도 있습니다. java -Xmx2g
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html


답변

  1. 내가 아는 한 힙 공간은 인스턴스 변수로만 차지합니다. 이것이 맞다면, 객체 생성시 인스턴스 변수를위한 공간이 할당 되었기 때문에 얼마 동안 잘 실행 된 후이 오류가 발생한 이유입니다.

즉, 일정 기간 동안 지속적으로 애플리케이션에 더 많은 개체를 만들고 있다는 의미입니다. 새 개체는 힙 메모리에 저장되며 이것이 힙 메모리의 증가 이유입니다.

힙은 인스턴스 변수 만 포함하지 않습니다. 기본이 아닌 모든 데이터 유형 (개체)을 저장합니다. 이러한 개체 수명은 짧거나 (메소드 블록) 길 수 있습니다 (개체가 응용 프로그램에서 참조 될 때까지).

  1. 힙 공간을 늘리는 방법이 있습니까?

예. 자세한 내용 은이 오라클 기사 를 참조하십시오.

힙 크기를 설정하기위한 두 가지 매개 변수가 있습니다.

-Xms : , 초기 및 최소 힙 크기를 설정합니다.

-Xmx : , 최대 힙 크기를 설정합니다.

  1. 힙 공간을 덜 차지하려면 프로그램을 어떻게 변경해야합니까?

응용 프로그램에 따라 다릅니다.

  1. 애플리케이션 요구 사항에 따라 최대 힙 메모리 설정

  2. 응용 프로그램에서 메모리 누수를 일으키지 마십시오.

  3. 애플리케이션에서 메모리 누수가 발견되면 MAT , Visual VM , jconsole 등과 같은 프로파일 링 도구를 사용 하여 근본 원인을 찾으십시오. 근본 원인을 찾으면 누수를 수정하십시오.

오라클 기사의 중요 참고 사항

원인 : Java 힙 공간에 대한 자세한 메시지는 Java 힙에서 개체를 할당 할 수 없음을 나타냅니다. 이 오류는 반드시 메모리 누수를 의미하지는 않습니다.

가능한 이유 :

  1. 부적절한 구성 (충분한 메모리를 할당하지 않음)
  2. 응용 프로그램이 의도하지 않게 개체에 대한 참조를 보유하고있어 개체가 가비지 수집되는 것을 방지합니다.
  3. 종료자를 과도하게 사용하는 응용 프로그램. 클래스에 finalize 메서드가있는 경우 해당 유형의 개체는 가비지 수집 시간에 공간을 회수하지 않습니다. 종료 자 스레드가 종료 대기열을 따라 잡을 수없는 경우 Java 힙이 채워질 수 있으며 이러한 유형의 OutOfMemoryError 예외가 발생 합니다.

다른 메모에서 더 나은 가비지 수집 알고리즘 ( CMS 또는 G1GC )을 사용하십시오.

G1GC를 이해하려면 이 질문 을 살펴보십시오.


답변

  1. 대부분의 경우 코드는 최적화되지 않습니다. 더 이상 필요하지 않을 것이라고 생각하는 물건을 놓으십시오. 매번 루프에서 객체를 생성하지 마십시오. 캐시를 사용해보십시오. 귀하의 응용 프로그램이 어떻게 작동하는지 모르겠습니다. 하지만 프로그래밍에서는 정상적인 생활의 한 가지 규칙도 적용됩니다.

    예방이 치료보다 낫습니다. “불필요한 개체를 만들지 마십시오”