Java Heap 구성
Java에서는 크게 두 가지 영역으로 메모리를 나누는데 Young 영역과 Old 영역이 그것이다.
Young 영역은 생긴지 얼마 안된 객체들을 저장하는 장소이고,
Old영역은 생성된지 오래된 객체를 저장하는 장소이다.
Perm 영역은 Class , Method 등의 정보가 저장되는 장소로 Code 가 올라가는 부분이라 GC 가 필요없다.
Minor GC
자바 힙의 가비지 컬렉션 대상인 Young영역의 GC 를 Minor GC 라고 부른다.
그리고 이 Young 영역은 Eden과 Survivor(Survivor 1, Servivor 2) 라는 두가지 영역으로 나뉘어 진다.
이중 Eden영역은 Java 객체가 생성되자 마자 저장이 되는곳이다.
생성된 객체중 레퍼런스가 특정 시간 뒤에도 살아있는 객체(Alive) 는
Minor GC가 발생할때 Survivor 1 영역으로 Copy 한다.
그럼 살아있지 않은 객체는 자연히 Suvivor1에 남아있게 되고,
남은 객체는 가비지 컬랙터에 의해 수집된다. ( 아래 그림의 빨간 객체 )
시간이 더 지나면 Eden 영역에 새로운 객체가 또 생기게 된다.
그리고 S1 에 있는 객체중 살아있는 객체도 있을 수 있다.
이 객체를 또다른 Survivor 객체 (S2) 로 옮긴다.
그리고 Eden 및 S1 에 남아 있는 객체는 가비지 컬랙터에 의해 수집된다.
계속 이런 방법을 반복적으로 수행하면서 Minor GC를 수행한다.
그리고 시간이 더 지나면 기준 시간을 넘은 객체는 OLD 영역으로 넘긴다.
그리고 남은 살아 있는 객체중 기준 시간이 넘지 않은 객체는 또다른 Survivor 객체로 옮긴다.
이런식으로 반복해 가면서 가비지 컬랙터에 컬랙션 되고 OLD 쪽으로 오래동안 살아남은 객체를 넘긴다.
Full GC
Old 영역의 Garbage Collection을 Full GC라고 부르며,
Full GC에 사용되는 알고리즘은 Mark & Compact라는 알고리즘을 이용한다.
Mark & Compact 알고리즘은 전체 객체들의 reference를 쭉 따라가다면서
reference가 연결되지 않는 객체를 Mark한다.
이 작업이 끝나면 사용되지 않는 객체를 모두 Mark가 되고, 이 mark된 객체를 삭제한다.
Full GC는 매우 속도가 느리며,
Full GC가 일어나는 도중에는 순간적으로 Java Application이 멈춰 버리기 때문에,
Full GC가 일어나는 정도와 Full GC에 소요되는 시간은
Application의 성능과 안정성에 아주 큰 영향을 준다.
EF Memory 사용량 체크
Commander.log 에 보면 서버의 메모리 상태를 주기적으로 체크하고 있으며
StatsD 로 이 데이터도 전송한다.
G1 Old Gen 분석
위 표에서 Full GC 가 일어나는 G1 Old Gen 부분을 수치적으로 아래와 같이 해석할 수 있다.
- 현재 커밋된 메모리는 ( 실제메모리 + 가상메모리 ) 9.48 GB
- 현재 사용중인 메모리는 7.182 GB
- 최대 메모리 사이즈는 12 GB
- 시작후 최대로 사용된 메모리는 8.282 GB
- 마지막 GC 이벤트후 메모리는 5.198 GB 로 복귀되었었음
- 1회 FullGC 의 평균 소요시간 1.1698 초 소요 (서버가 평균 1초씩 멈춤)
|
이중 주의해서 볼 부분이 Peak 메모리 사용량과 FullGC 의 횟수 및 평균 소요 시간이다.
최대 메모리가 낮으면 JAVA가 old-gen 메모리를 약간 더 자주 수집하게 되지만
GC 이벤트에 필요한 시간을 최소한으로 유지하게 된다.
반대로 Heap 메모리를 너무 높게 설정하면 Full GC 는 적게 일어나지만
서버의 메모리를 계속 점유하고 있을 가능성이 많으며
한번 GC 이벤트가 발생하면 몇 초 이상씩 멈춰있을 수도 있게 된다.
사용 메모리가 최대치에 근접한 피크 메모리 이벤트가 자주 발생하는지도 주의해서 보아야 한다.
EF 에서는 특히 아래와 같은 작업을 수행하게 되면 메모리 피크가 발생할 수 있다.
메모리 피크가 너무 극심하면 이로 인해 메모리 오버플로우 현상이 생길 수도 있다.
즉 Full GC 로 Collect 될 수 없는 사용중인 객체가 너무 많아서
힙 사이즈 설정 범위를 넘어가버리는 경우가 생길 수 있다.
아래와 같은 작업의 경우 이와 같은 상황을 만들 수 있으므로 주의해서 사용해야 한다.
큰 프로젝트 Export
Job 을 포함한 Export (실행중인 시스템에서 성공을 보장하지 않음)
특정 동작으로 인해 임시 메모리 피크가 발생할 수 있습니다.
많은 양의 동시 작업 또는 워크플로실행
Grafana 에서 메모리 사용량 확인
앞서 "ElectricFlow 에서 StatsD로 데이터 전송" 부분의 셋팅이 끝난 상태라면
Grafana 에서 EF 를 모니터링 할 수 있게 된다.
이중 Memory 를 모니터링 하기 위해서는 아래와 같이 설정하면 되겠다.
Reference
'Monitoring > Grapana+Graphite+Statd' 카테고리의 다른 글
12. Graphite - Metrics (0) | 2020.01.22 |
---|---|
11. Grafana - Panels (0) | 2020.01.22 |
10. Grafana - DataSource (0) | 2020.01.22 |
09. Grafana - Dashboard (0) | 2020.01.22 |
08. Grafana - Admin (0) | 2020.01.22 |