본문 바로가기

개발중/troubleshooting

GC overhead limit exceeded 에러 확인하기

728x90
반응형

 

발생 에러

[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.OutOfMemoryError: GC overhead limit exceeded] with root cause 
java.lang.OutOfMemoryError: GC overhead limit exceeded
 at java.util.Arrays.copyOf(Arrays.java:3181)
 at java.util.ArrayList.grow(ArrayList.java:265)
 at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
 at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
 at java.util.ArrayList.add(ArrayList.java:462)
 at org.apache.xmlbeans.impl.store.Saver.addMapping(Saver.java:675)
 at org.apache.xmlbeans.impl.store.Saver.<init>(Saver.java:99)
 at org.apache.xmlbeans.impl.store.Saver$SynthNamespaceSaver.<init>(Saver.java:903)

 

  • CPU 사용량중 98%이상이 GC가 작동되는 경우 GC Overhead limit exceeded가 발생이 된다.
  • 한정된 Heap Memory안에서 GC 대상의 객체는 없지만 새롭게 생성되는 객체가 메모리를 할당하지 못할경우에 GC의 시간이 길어지게된다. 
  •  

 

에러가 발생되는 예제 코드

map에서 계속해서 데이터를 넣는 샘플데이터

class Wrapper {
  public static void main(String args[]) throws Exception {
    Map map = System.getProperties();
    Random r = new Random();
    while (true) {
      map.put(r.nextInt(), "value");
    }
  }
}
 
  • reference가 존재하기 때문에 메모리가 부족할때 대부분의 cpu를 gc에 사용을 하게 되고 GC overhead limit exceeded 에러가 발생된다.
 

 

해결방법

1. GC overhead limit exceeded Option 끄기

-XX:-UseGCOverheadLimit
  • 추천하지 않는 방법
  • GC overhead limit exceeded 가 왜 나왔는지 문제를 파악해야합니다.

2. heap 메모리 설정

java -Xmx1024m com.yourcompany.YourClass
  • 데이터 읽는 양이 많을 경우
  • -Xmx : 최대 Heap Memory 설정
  • -Xms : 최소 Heap Memory 설정

 

 

저는 실제로 어플리케이션이 사용하고 있는 메모리 수치를 확인하기 위해 jvisualvm.exe 를 켜서 메모리의 사용량을 실시간으로 확인을 하고 그에 맞는 메모리 설정을 했습니다. 

 

jvisualvm.exe  의 위치는 보통 아래와 같습니다.

 

 

 

힙 메모리 사용량도 확인이 가능하기 때문에 OutOfMemoryError: Java heap space 에러에 대처할 수 있었습니다.

 

 

 

728x90
반응형