[java] 오류 java.lang.OutOfMemoryError : GC 오버 헤드 한계를 초과했습니다

JUnit 테스트를 실행할 때이 오류 메시지가 나타납니다.

java.lang.OutOfMemoryError: GC overhead limit exceeded

나는 무엇인지 알고 OutOfMemoryError있지만 GC 오버 헤드 제한은 무엇을 의미합니까? 이 문제를 어떻게 해결할 수 있습니까?



답변

이 메시지는 어떤 이유로 가비지 콜렉터가 과도한 시간 (기본적으로 프로세스의 모든 CPU 시간의 98 %)을 소비하고 각 실행에서 매우 적은 메모리 (기본적으로 힙의 2 %)를 복구 함을 의미합니다.

이것은 효과적으로 프로그램이 진행을 멈추고 가비지 수집 만 항상 실행 중임을 의미합니다.

아무런 작업도 수행하지 않고 애플리케이션이 CPU 시간을 흡수하지 못하도록하기 위해 JVM이이를 처리 Error하여 문제점을 진단 할 수 있습니다.

제가보기에 드문 경우는 일부 코드가 이미 메모리가 매우 제한된 환경에서 수많은 임시 객체와 약하게 참조 된 많은 톤을 생성하는 경우입니다.

다양한 Java 버전에서 사용할 수 있으며이 특정 문제에 대한 섹션이 포함 된 Java GC 튜닝 안내서를 확인하십시오.


답변

오라클의 기사 “Java SE 6 HotSpot [tm] 가상 머신 가비지 콜렉션 튜닝” 에서 인용 :

과도한 GC 시간 및 OutOfMemoryError

가비지 수집에 너무 많은 시간이 소비되면 병렬 수집기는 OutOfMemoryError를 발생시킵니다. 총 시간의 98 % 이상이 가비지 수집에 소비되고 힙의 2 % 미만이 복구되면 OutOfMemoryError가 발생합니다. 이 기능은 힙이 너무 작아서 진행이 거의 또는 전혀 발생하지 않으면 서 애플리케이션이 장시간 실행되지 않도록하기 위해 설계되었습니다. 필요한 경우 옵션 -XX:-UseGCOverheadLimit을 명령 줄 에 추가하여이 기능을 비활성화 할 수 있습니다 .

편집 : 누군가 나보다 빨리 입력 할 수있는 것처럼 보입니다 🙂


답변

프로그램에 메모리 누수 가없는 경우 다음을 시도하십시오.

  1. 예를 들어 힙 크기를 늘리십시오 -Xmx1g.
  2. 동시 낮은 일시 중지 수집기를 활성화합니다 -XX:+UseConcMarkSweepGC.
  3. 가능하면 기존 객체를 재사용하여 메모리를 절약하십시오.

필요한 경우 옵션 을 명령 줄 에 추가 하여 제한 검사 를 비활성화 할 수 있습니다 -XX:-UseGCOverheadLimit.


답변

일반적으로 코드입니다. 다음은 간단한 예입니다.

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Windows 7 32 비트에서 Java 1.6.0_24-b07 사용.

java -Xloggc:gc.log GarbageCollector

그럼 봐 gc.log

  • BAD 방법을 사용하여 444 회 트리거
  • WORSE 방법을 사용하여 666 번 트리거
  • BETTER 방법을 사용하여 354 번 트리거

이제 이것은 최고의 테스트 나 최고의 디자인은 아니지만 그러한 루프를 구현하는 것 외에 다른 루프를 구현하거나 잘못 작동하는 기존 코드를 처리 할 때 새로운 코드를 생성하는 대신 객체를 재사용하도록 선택할 수 있습니다. 가비지 수집기가 방해가되는 횟수


답변

Java [8] Platform, Standard Edition 문제 해결 안내서 에 따른 오류의 원인 : (강조 및 줄 바꿈 추가)

[…] “GC 오버 헤드 한계 초과”는 가비지 콜렉터가 항상 실행 중이며 Java 프로그램이 매우 느리게 진행되고 있음을 나타냅니다.

가비지 콜렉션 후 Java 프로세스가 가비지 콜렉션을 수행하는 데 시간의 약 98 % 이상을 소비 하고 힙의 2 % 미만을 복구하고 있으며 마지막 5 (컴파일 시간 상수) 연속 가비지 인 경우 컬렉션이 java.lang.OutOfMemoryError있으면 a 가 발생합니다. […]

  1. 현재 힙이 충분하지 않은 경우 힙 크기를 늘리십시오 .
  2. 힙 메모리를 늘린 후에도이 오류가 계속 발생하면 MAT (메모리 분석기 도구), Visual VM 등과 같은 메모리 프로파일 링 도구를 사용 하고 메모리 누수를 수정하십시오.
  3. JDK 버전을 최신 버전 (1.8.x) 또는 1.7.x 이상으로 업그레이드하고 G1GC 알고리즘을 사용하십시오. . G1 GC의 처리량 목표는 90 %의 응용 프로그램 시간과 10 %의 가비지 수집 시간입니다.
  4. -로 힙 메모리를 설정하는 것 외에도 Xms1g -Xmx2g시도하십시오

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n

G1GC에 관한 몇 가지 관련 질문을 살펴보십시오


답변

이 옵션을 설정하여 힙 크기를 약간 늘리십시오.

실행 → 구성 실행 → 인수 → VM 인수

-Xms1024M -Xmx2048M

Xms- 최소 한계

Xmx- 최대 한계


답변

나를 위해 다음 단계가 효과적이었습니다.

  1. 열려있는 eclipse.ini파일을
  2. 변화

    -Xms40m
    -Xmx512m

    -Xms512m
    -Xmx1024m
  3. 이클립스 다시 시작

여기를 봐