[JBoss EAP] GC LOG
본문 바로가기
IT 이야기/JBoss EAP

[JBoss EAP] GC LOG

by 찬찬이 아빠 2020. 10. 20.
반응형

GC(Garbage Collection)이란 Java 언어에서 오브젝트에 대한 메모리 할당과 해제는 Java 가상 머신이 자동으로 관리하는데 이때 메모리에서 사용된 오브젝트를 자동으로 제거하는 메커니즘을 말합니다.

 

Java 가상 머신은 실행되고 있는 Java 프로그램 내에서 어디에도 참조되지 않는 불필요한 Java 오브젝트를 찾아 해당 영역의 메모리를 자동으로 해제합니다. 이렇게 Java 오브젝트를 자동으로 제거하는 방법을 '가비지 컬렉션(GC)'이라고 합니다. Java 가상 머신 내부에서 가비지 컬렉션은 별도의 스레드로 주지적으로 동작합니다. 이 가비지 컬렉션이 동작하는 주기는 Java 가상 머신의 힙의 크기와 애플리케이션에서 힙 메모리를 어떻게 사용하는지에 따라 달라지게 됩니다.

 

Java 애플리케이션이 실행되면 오브젝트는 메모리에 로드됩니다. 사이즈가 큰 객체를 사용하거나 사용하는 오브젝트 개수가 많으면 그 만큼 메모리 사용량이 증가합니다 Java에서 사용 가능한 메모리 영역을 힙(Heap) 영역이라고 합니다. 힙 영역 이외에도 Permanent 영역이 존재합니다. 새롭게 생성된 오브젝트들을 계속 로드하면 Java가 사용할 수 있는 메모리 공간이 가득차게 됩니다.

 

Java 애플리케이션에서 사용하는 메모리 종류는 아래와 같습니다.

 

<Java Heap 영역>

  • 사용자가 생성하는 Java 오브젝트들이 거주하는 공간
  • -Xms와  -Xmx 옵션으로 설정

 

<Permanent 영역>

  • Class에 대한 메타 정보를 저장하는 공간
  • -XX:PermSize와 -XX:MaxPermSize 옵션으로 설정

 

<Native Heap 영역>

  • Java 오브젝트가 아닌 Native 오브젝트들이 거주하는 공간
  • JVM 옵션으로 설정할 수 없으면 OS에서 자동 설정

 

메모리가 가득 차면 새 객체를 로드할 수 없어서 프로그램을 실행할 수 없는 상황이 발생합니다. 그래서 이를 방지하기 위한 구조가 가비지 컬렉션(GC) 입니다. 힙에 여유가 없을 때 사용되는 객체와 사용되지 않는 객체를 판별하여 사용되지 않은 객체를 청소 대상으로 하여 메모리에서 삭제하는 방법으로 메모리 공간을 확보합니다.

 

가비지 컬렉션은 메모리 관리의 장점이 있지만, 반면 이 때문에 애플리케이션의 성능이 감소하고, 응답 시간이 지연되는 등 성능 병목 현상의 원인이 될 수 있습니다.

 

서비스를 운영하다보면 아래와 같은 GC 로그 메시지를 보게 될 것입니다.

 

1580612.377: [GC  [PSYoungGen: 414250K->288K(680960K)] 555159K->141196K(2079232K), 0.0102030secs] [Times: user=0.03, sys=0.00, real=0.01 secs]

1580612.388: [Full GC [PSYoungGen: 288K->0K(680960K)] [ParOldGen: 140908K->138286K(1398272K)] 141196K->138286K(2079232K) [PSPermGen: 103271K->103259K(103424K)], 0.3900350 secs] [Times: user=0.98, sys=0.00, real=0.39 secs]

1584029.871: [GC [PSYoungGen: 662528K->7324K(680960K)] 800814K_>145610K(2079232K), 0.0273790 secs] [Times: user=0.05, sys=0.00, real=0.03 secs]

1584212.780: [GC [PSYoungGen: 354594K->2146K(682496K)] 492881K_>143576K(2080768K), 0.0134140 secs] [Times: user=0.04, sys=0.01, real=0.02 secs]

1584212.794: [Full GC [PSYoungGen: 2146K->0K(682496K)] [ParOldGen: 141429K->140121K(1398272K)] 143576K->140121K(2080768K) [PSPermGen: 103287->103284K(103424K)], 0.4031760 secs] [Times: user=1.03, sys=0.00, real=0.40 secs]

... 생략 ...

 

GC 로그에서 Full GC가 3600초 이전에 발생하게 되면 GC로 인해 서비스에 영향을 미치게 됩니다. 이때는 JBoss EAP의 노드별 메모리 설정을 튜닝해야 합니다.

 

다음은 GC 로그에서 많이 발생하는 에러 코드와 예시를 설명하려고 합니다.

① java.lang.OutOfMemoryError: GC overhead limit exceeded

 

위와 같은 에러 메시지는 메모리가 부족하여 가비지 컬렉션(GC)이 이루어졌으나 새로 확보된 메모리가 전체 Heap 메모리의 2% 미만이어서 이후 작업이 수행 불가일 경우 발생하는 GC 에러 로그입니다.

 

② java.lang.OutOfMemoryError: Java heap space

 

위와 같은 에러 메시지는 Heap 메모리 공간이 부족하여 더 이상 사용할 수 없을 경우 발생하는 GC 에러 로그입니다.

 

 

위 처럼 GC 로그가 발생하여 JBoss EAP 노드의 Java 옵션 설정을 해야 할 경우 어떻게 해야 할까요?

 

Java 1.7 기준으로 설명을 하겠습니다.

우선 Java  옵션을 설정할 파일의 위치를 알아야합니다.

$JBOSS_HOME/domains/노드명/bin/env.sh 파일에 Java 옵션을 설정할 수 있습니다.

 

해당 파일을 vim으로 열어 export JAVA_OPTS 라고 검색을 합니다.

아래는 JAVA_OPTS 설정 예시입니다.

export JAVA_OPTS=" $JAVA_OPTS -Xms2048m -Xmx2048m -XX:MaxPermSize=512m"

 

각 JBoss EAP 노드별 Heap 메모리 영역의 설정을 최대/최소 2GB로 설정하고 MaxPermsize를 512MB로 설정하였습니다.

 

만약 JBoss EAP 노드별 사용 메모리가 JAVA_OPTS에 설정된 Heap 메모리 크기를 초과한다면 Heap 메모리 설정 변경이 필요합니다.

 

참고사항으로 Java 1.8에서는 Java  애플리케이션 메모리 영역이 변경되었습니다.

Permanent 영역과 Native Heap 영역이 MetaSpace 영역으로 통합되었습니다.

MetaSpace 영역에서는 Class에 대한 메타 정보를 저장하고 -XX:MetaSpaceSize와 -XX:MaxMetaSpaceSize 옵션으로 설정이 가능합니다.

반응형

댓글