티스토리 뷰

728x90
반응형

 포스팅은 HotSpot 계열 JDK의 GC Log 분석 가이드입니다.


GCLog는 다양한 플랫폼 JVM의 Working 상태를 분석하고, 메모리 사용패턴을 진단하여 효율적인 Gabage Collector를 수집할 수 있도록 도와주는 역할을 합니다. 


GC log

JAVA Memory 관리 구조

Java의 메모리는 기존의 C 언어와는 전혀 다른 구조로 사용되며 관리됩니다.

Java에서의 메모리 관리는 C 언어의 malloc과 같은 메모리 관련 메소드를 통하는 것이 아니라, Java 자체적으로 더 이상 사용하지 않는 메모리를 자동으로 해제해 주는 기능 (GC : Garbage Collection)이 제공됩니다.


GC LOG를 통해 분석이 필요한 경우

[OutOfMem 발생한 경우]

GC Log를 통해 Java 메모리를 분석해야 할 가장 중요한 시점은 OOM이 발생할 경우입니다.

OOM이 발생하는 경우는 말 그대로 Java Heap 메모리가 부족하여 더 이상 가용한 메모리가 경우라 할 수 있습니다이러한 OOM이 발생하는 경우는 두 가지 정도라고 할 수 있는데메모리 leak으로 인한 OOM과 순간적으로 과도한 메모리 할당으로 인해 발생하는 OOM 경우로 볼 수 있습니다

OOM이 발생할 경우 GC Log 분석을 통해 어느 경우에 의해 발생하였는지 확인 할 수 있으나두 경우 모두 실제 문제를 해결하기 위해서는 Heapdump 분석 등의 다른 분석 방법을 적용해야 합니다.

 

[사용자의 요청 처리 시간이 일정하지 않은 경우]

OOM으로 인해 프로세스에 장애가 발생할 수 있으나, GC로 인한 Java 프로세스 멈춤 현상이 발생할 수도 있습니다.

이러한 멈춤 현상은 짧게는 0.001초에서 길게는 수십 초가 걸릴 수도 있습니다.

사용자의 요청 처리가 빠르게 처리되다 간혹 느려지는 현상이 발생한다면여러 가지 원인이 있겠으나 GC로 인한 STW 현상도 의심해 봐야 할 것입니다.


Sun 계열 메모리

메모리 구조

[Sun 계열의 메모리 구조]

Sun 계열의 Java Generational Heap으로 구성되어 있습니다.

 Generational Heap이란 object들의 기간에 따라 위치하게 되는 지점이 달라지는 되는 구조입니다.

Sun 계열의 Java에서는 이러한 Generational Heap의 구조를 크게 Young(New) Generational Old Generational 영역으로 구성하고 있으며, Young Generational은 다시 Eden 영역과 Survivor영역으로 구성되어 있습니다.

Young(New) Generation Java object가 생성될 때 저장되는 공간이며, 또한 생성 된지 얼마 되지 않는 객체들이 저장되는 공간입니다. object가 생성되면 이 영역에 저장되었다가 시간이 지남에 따라 해제되지 않는 object들은 Old Generation으로 옮겨지게 됩니다.

따라서 Old Generation Young 영역에서 저장되었던 객체 중에 오래된 객체가 이동되어서 저장되는 영역이라 할 수 있습니다. Perm Generation이라는 영역은 Class에 대한 메타정보가 저장되는 영역입니다.

 

[Sun 계열 Java의 메모리 구조에 대한 그림]

New 영역은 Eden, To, From 으로 구분되며 New Old를 합쳐 초기 Heap size가 결정됩니다. 실제 할당되는 메모리의 크기 옵션은 -Xms로 설정이 가능합니다.

New Old 그리고 추가적인 확장 영역을 합쳐 최대 Heap size가 결정됩니다. 실제 할당되는 메모리의 크기 옵션을 -Xmx로 설정이 가능합니다.

그 이외에 New의 크기 설정 하기 위해 -Xmn 옵션을 사용하며, Perm 영역 설정을 위해 -XX:PermSize 옵션을 사용할 수 있습니다.

 

[Sun 계열 Java GC 동작 방식]

- 구조

GC가 동작하는 목적은 Garbage를 어떻게 효율적으로 청소하느냐 입니다. 기본적으로 GC Young 영역이 가득 차게 되거나, Old 영역이 가득 차거나 또는 Old 공간의 작아 Young 영역의 Live object를 옮길 수 없을 때(can't being promoted) 발생하게 됩니다.

Perm 영역은 Class등의 메타정보가 저장되는 부분이므로, ClassLoader가 해제되지 않는다면 일정한 수치를 유지하는 것이 일반적입니다. 물론 ClassLoader의 문제로 인해 중복된 Class의 메타 정보가 로드 되어 Perm 영역에 대한 OOM (OutOfMemory)가 발생할 수 있습니다.

Young 영역에 대한 GC를 통상 Minor GC(Young GC)라 하며, Old 영역의 GC Major GC(Full GC)라고 부릅니다.

Minor GC Copy&Scavenge라는 알고리즘을 사용하며, 이 알고리즘의 방식은 속도가 매우 빠르며 작은 크기의 메모리를 Collection하는데 매우 효과적입니다.

이에 반해 Full GC Mark&Sweep, Compact라는 알고리즘을 사용하며, 이 방식은 전체 객체들의 reference를 쭉 따라가면서 reference가 연결되지 않은 객체를 Mark하며, Mark된 객체를 삭제하게 됩니다. 이러한 방법으로 인해 수행 속도가 느립니다.


Minor GC의 동작 방식

Minor GC Young 영역에 대한 GC를 담당하며, Young Eden Survivor라는 두-가지 영역으로 구성되어 있습니다.

Eden 영역은 객체가 생성되자 마자 저장이 되는 곳이며, Survivor 영역은 alive 객체를 저장하기 위한 영역입니다.

 

[Minor GC의 단계별 작동 방식]

Minor GC의 작동 방식의 원활한 설명을 위해 다음의 옵션을 먼저 설명 드리도록 하겠습니다.

"-XX:MaxTenuringThreshold"  object Old 영역으로 이동(promotion)되기 위한 Minor GC의 횟수를 설정하는 값으로 이 값에 따라 object New 영역에 얼마나 오래 존재할 지에 대한 시간이 정해집니다.

아래의 동작 방식은 설명의 편의상 MaxTenuringThreshold 값이 2일 경우에 대한 내용입니다. 기본값인 31은 아래의 내용을 31번까지 지속한다고 보시면 됩니다.

 

1. 새롭게 생성된 object들이 Eden 영역에 저장됩니다.

 

2. Eden 영역이 Full이 되어 live object의 리스트를 확인합니다.

 


3. 확인 된 live object들을 To 영역으로 copy를 수행합니다.

 


4. live object To로 이동되었으며, Eden 영역은 garbage만 남아 있습니다.

 


5. Eden garbage scanvenge하여 깨끗하게 만듭니다. (minor collection) 이 작업 후에는 Eden 영역이 항상 깨끗하게 비어지게 됩니다. 그리고 To live object TeunuringThreshold 값이 1이 됩니다.

 


6. 다른 object들이 새롭게 생성되면서 Eden 영역이 가득 차게 되며, 이 때 Eden To 영역의 live object의 리스트를 확인합니다.

 


 

7. Eden To live object from으로 copy 합니다. 그리고 Eden To에는 garbage만 남게 됩니다.

 


8. Eden To garbage scavenge하여 깨끗하게 만듭니다. (minor collection). 그리고 기존에 To 영역과 From 영역의 이름을 바꾸어 줍니다. 그렇게 되면 To 영역에는 TenuringThreshold 값이 1(Eden으로부터 넘어옴), 2(기존 To 영역영역부터 넘어옴) live object만 남게 됩니다.

 


9. 다시 다른 object들이 새롭게 생성되면서 Eden 영역이 가득 차고 live object TenuringThreshold의 값을 확인합니다.

 


 

10. 이 때 To 영역의 TenuringThreshold 값이 2 object들이 처음으로 promotion (new -> old로 이동) 됩니다.

 


 

11. promotion이 일어나면 live object Old 영역에 저장되며 TenuringThreshold 값이 3으로 변경됩니다.

 


12. 그리고 가득 찬 Eden 영역을 해소하기 위해 Eden To 영역의 live object를 확인하여 From으로 이동시킵니다.

 


13. live Object의 이동이 완료되면 From에는 object들의 TenuringThreshold값이 Eden에서 옮겨온 object 1 To에서 옮겨온 Object 2로 설정됩니다.

 


14. copy가 완료되면 Eden To 영역을 scavenger하여 깨끗하게 만듭니다. (minor collection) 또한 To 영역과 From 영역의 이름을 바꿔줍니다.

 


 


Minor GC의 동작 방식은 위와 같습니다. MaxTenuringThreshold 값 만큼 위와 같은 minor collection이 수행되면서 object들이 promotion(new -> old) 됩니다.

위와 같이 Minor GC는 지속적으로 생성되는 object들을 copy&scavenge를 통해 관리하게 되며 객체의 생명주기가 긴 경우 old영역으로 이동 시키게 됩니다.


Major GC의 동작 방식

1. Minor GC가 지속적으로 수행되면서 promotion이 발생하게 되면 old 영역이 가득 차게 됩니다.


2. old 영역이 가득 차게 되면 Major GC가 발생하며 old영역의 object에 대해 Mark Sweep, Compact 작업을 통해 더 이상 사용하지 않는 object를 삭제하고 메모리 연속된 여부 공간을 확보하기 위해 앞쪽으로 정렬하는 작업을 수행합니다.


Major GC old 영역의 모든 object에 대해 참조정보를 확인하여 Mark하고, 해당 object를 삭제하기 위해 Sweep 작업을 실시합니다. 그리고 마지막에 할당 가능한 메모리 공간을 확보하기 위한 Compact 작업을 수행합니다. 이러한 일련의 작업을 수행하기 때문에 object의 수가 많을수록 수행하는 시간은 길어 질 수 밖에 없습니다.


다양한 GC 방식

Minor GC Major GC GC를 위한 기본적으로 수행되는 방식이며, 이 방식을 기본 하에 여러 가지 기능을 추가하여 다양한 GC 방식이 제공됩니다.

가장 일반적으로 사용하는 방식은 Serial GC 방식이며, 여러 개의 Thread GC를 처리하는 Parallel GC, STW(Stop the world)라는 단점을 보완하기 위한 Concurrent GC, Incremental GC등이 있습니다.

 

[Serial GC]

Serial GC Minor GC Major GC가 정상적으로 수행되는 것입니다. 가장 기본적인 GC입니다.

하나의 Thread GC를 수행합니다.

 

[Parallel GC]

Parallel GC는 동시에 여러 개의 Thread GC를 수행하게 되며, 이렇게 함으로써 GC의 수행 시간을 최소와 하는 것입니다. Parallel GC가 빠르게 수행되기 위해서는 CPU 수와 연산 속도에 밀접한 관계가 있습니다. 일반적으로는 GC 수행 시 서버의 CPU Core수 만큼 Thread가 기동되어 GC를 수행합니다. 따라서 CPU Core가 많고 속도가 빠르다면 GC 수행 속도가 빨라지는 것이 일반적입니다.

Parallel GC Minor GC에 기본적으로 적용(-XX:+UseParallelGC)되며, Major GC는 별도의 옵션(-XX:+UseParallelOldGC)이 필요합니다. 또한 사용 가능한 GC Thread도 지정(-XX:ParallelGCThreads)이 가능합니다.

 

[CMS GC]

CMS(Concurrent Mark&Sweep) GC JVM이 멈추는 시간을 최소화하는 것입니다.

CMS GC Major GC로 인한 JVM이 멈추는 시간을 최소화 하는 것으로, Initial mark, Concurrent mark, Remark, Concurrent Sweep, Concurrent reset의 단계를 거치게 되며, 이러한 단계 중 Initial mark Remark 단계에서만 STW가 발생되어 STW 현상이 최소화 됩니다.

 

[Incremental GC]

Incremental GC CMS GC와 같이 Major GC로 인한 JVM이 멈추는 현상을 최소화하기 위한 방법입니다.

Incremental GC Minor GC가 일어날 때 마다 old 영역을 조금씩 GC를 수행해서 Major GC가 발생하는 회수나 시간을 줄이는 방법입니다.


GC Tuning은 성능에 지대한 영향을 주는 요소 중 하나입니다. 다양한 Policy를 적용해 보고 이를 적재적소에 반영하는 것은 경험과 환경 그리고 Application을 분석할 수 있는 능력에서 나온다고 볼 수 있습니다.

728x90
반응형