Garbage Collection(GC)
GC는 reachability라는 개념을 사용해 참조되지 않는 객체들의 메모리를 회수하는 역할을 하여 자바에서는 명시적으로 메모리를 지정하여 해제하지 않는다.
Minor, Major GC -Heap 영역에 객체가 생성되면 최초로 Eden 영역에 할당되고 이 영역에 어느정도 데이터가 쌓이게 되면 참조정도에 따라 Servivor1, Servivor2 중 빈 공간으로 이동된다.
New Generation과 Tenured Generation 에서의 GC를 Minor GC 라고 한다.
Old영역에 할당된 메모리가 허용치를 넘게 되면, Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제하는 GC가 실행되는데 시간이 오래 걸리는 작업이고 이 때 GC를 실행하는 쓰레드를 제외한 모든 스레드는 작업을 멈추게 된다.
이를 ‘Stop-the-World'라 하고 Old영역의 메모리를 회수하는 GC를 Major GC라고 한다.
Major GC가 실행되면 이것이 종료될 때 까지 다른 모든 쓰레드가 멈추기 때문에 성능에 영향을 끼친다.
GC는 항상 background 에서 데몬 쓰레드 (보조 쓰레드)로 돌아가면서 접근 불가능한 상태가 된 객체를의 메모리를 정리해준다.
JVM의 메모리 공간에는 Young Generation / Old Generation 이라는 두가지의 물리적 공간이 존재한다.
- Young Generation 영역 : 새롭게 생성한 객체가 위치한다. 많은 객체가 이 영역에 생성되었다 사라지며 이를 Minor GC라고 한다.
- Old Generation 영역 : 접근불가능한 상태가 되지않아 Young 영역에서 살아남은 객체가 이 영역으로 복사된다. Young 영역보다 크게 할당되며 GC는 적게 발생한다. 이 영역에서 객체가 사라질 때 Major GC 또는 Full GC 가 발생한다.
Minor GC가 발생하는 동안 Survivor1, Survivor2 영역을 오가며 살아남은 객체들은 최종적으로 Old Generation 영역으로 옮겨지며, Old Generation 영역에 있다가 미사용된다고 식별되는 객체들은 Full GC를 통해 메모리에서 제거된다.
Young Generation 영역에서 오래동안 살아남은 객체는 Old Generation 영역으로 옮겨지는데, 오래되었다는 기준은 무엇일까?
오래되었다고 하는 기준은 Young Generation 영역에서 Minor GC 가 발생하는 동안 얼마나 오래 살아남았는지로 판단한다.
각 객체는 Minor GC에서 살아남은 횟수를 기록하는 age bit 를 가지고 있으며, Minor GC가 발생할 때마다 age bit 값은 1씩 증가 하게되며, age bit 값이 MaxTenuringThreshold 라는 설정값을 초과하게 되는 경우 Old Generation 영역을 객체가 이동 되는 것이다.
또는 Age bit가 MaxTenuringThreshold 초과하기 전이라도 Survivor 영역의 메모리가 부족할 경우에는 미리 Old Generation 으로 객체가 옮겨질 수도 있다.
GC 방식 (JDK7 기준)
1. Serial GC - Serial GC는 데스크톱의 CPU 코어가 하나만 있을 때 사용하기 위해서 만든 방식이다.
Serial GC를 사용하면 애플리케이션의 성능이 많이 떨어진다. Mark-sweep-compact 알고리즘이 사용된다. Old 영역에 살아있는 객체를 Mark 하고 Heap의 앞부분부터 살아있는 객체를 Sweep한 뒤, 힙의 앞부분부터 객체를 쌓는다.(Compact) 메모리와 CPU 코어수가 적을 때 좋다.
2. Parallel GC : Serial GC와 기본적인 알고리즘은 같지만, GC를 처리하는 Thread의 개수가 여러 개다. 메모리와 CPU 코어 수가 많을수록 좋다.
3. Parallel Old GC : Parallel GC와 같지만 Old 영역의 GC 알고리즘만 다르다. Mark-Summary-Compact 알고리즘이며 조금 더 복잡하다.
4. CMS GC : Stop-the-world 이후 Initial marking 시 살아있는 객체만 찾는다. 이후 concurrent mark 단계에서 참조를 따라가며 새로 추가되거나 참조가 끊긴 객체들을 remark 한다. 모든 작업이 멀티스레드 환경에서 동시진행되기 때문에 stop-the-world 시간이 매우 짧은 대신 memory와 CPU 를 많이 사용하고 compaction 단계가 제공되지 않는다.
5. GI GC : Young 영역과 Old 영역이 없이 매우 빠르게 객체를 할당하고 GC한다.
메모리 관련 GC 튜닝을 위한 JVM 옵션
-Xms : JVM 시작 시 힙 영역의 크기
-Xmx : 최대 힙 영역 크기
-XX:NewRatio : New 영역과 Old 영역의 비율. (New 영역의 비율을 전달한다.)
-XX:NewSize : New 영역의 크기
-XX:SurvivorRatio : Eden 영역과 Survivor 영역의 비율 (Survivor 영역의 비율을 전달한다.)
'Language & Framework > Java' 카테고리의 다른 글
[JAVA] :: 자바 기초 1 :: 객체 / 클래스 / 인스턴스 / 속성 / 함수 / 메소드 (2) | 2021.07.04 |
---|---|
[JAVA] 소켓(socket) 프로그래밍 (0) | 2021.01.20 |
[JAVA]입출력 IO & NIO (0) | 2021.01.20 |
[JAVA] 자바 컴파일은 어떻게 동작할까? (0) | 2021.01.18 |
[JAVA] JDK, JRE, JVM이란? (0) | 2021.01.18 |