article thumbnail image
Published 2023. 10. 22. 00:50
728x90

Garbage Collection Concept


GC가 이루어지는 영역은 young generation 과 old generation 으로 나뉘며 JVM 의 heap 영역에 할당된다. young generation 은 Eden 과 2개의 survivor space 로 나뉜다. old generation 은 old space 로 나뉜다.

young generation 이 꽉 차게 되면 minor gc 가 이루어지고, 살아남은 객체는 old 영역으로 이동을 하게 된다. old 영역은 minor 영역보다 메모리 공간이 더 많고 큰 객체나 young 영역에서 살아남은 = 객체들을 보관한다. old 영역도 young 영역에서 이루어지는 minor gc 와 마찬가지로 공간이 꽉차게 되면 garbage collecting 을 실행하게 되는데 이를 major gc 라고 한다.



Young


객체가 새로 할당되면 young generation 의 eden 영영에 할당이 이루어지고, eden 영역이 꽉 차게 되면 garbage collecting 을 실시하게 된다. 이때 아직 사용되고 있는 객체들은 survivor 영역으로 이동을 하게 된다. survivor 영역은 2개로 나뉘어져 있고, 이 중 하나는 항상 비어있는 상태로 유지가 된다.
eden 영역 꽉참 -> garbage collecting 실시 -> 살아남은 객체 survivor(0 - from space) 영역으로 이동
-> 다시 eden 영영 꽉참 -> garbage collecting 실시 -> survivor(0 - from space) 의 살아남은 객체들을 survivor(1 - to space)로 옮긴다.
-> 이 같은 과정을 반복하다 survivor(1 - to space)의 영역의 살아남은 객체들은 old generation 영역으로 옮기게 된다.



Old


old 영역은 young generation 영역에서 계속해서 살아남은 객체들이 넘어오는 영역이며 마찬가지로 꽉차게 되었을 때 gc 가 발생한다. 이때 발생하는 gc 가 major gc 이다. Old 영역은 young 영역보다 공간이 크기 때문에 gc가 발생하는 숫자는 적지만 major gc 는 minor gc 보다 시간이 오래 걸린다.
** old 영역이 JVM의 heap 영역에 할당되는 default 값은 heap 영역의 2/3 이며 young gen은 1/3을 차지하게 된다. 하지만 초기 young gen에 할당되는 공간이 적으면 적을수록 빠르게 minor gc 가 발생하고 그만큼 old 영역으로 넘어가는 객체가 많아지게 된다. old 영역으로 객체가 빠르게 넘어오게 되면 major gc 의 발생 횟수가 많아지게 되고 이는 성능상의 문제와 연결될 수 있다. 따라서 초기에 JVM 설정을 통해 heap 공간의 young 영역의 공간 할당을 늘려주는 것이 좋다.
-Xms, -Xmx - Heap 사이즈의 최소, 최대값
-XX:NewSize - Young Generation의 영역의 초기 사이즈
-XX:MaxNewSize - Young Generation의 최대 사이즈
-XX:NewRadio - 위와 같을 경우 Old Generation은 Young Generation의 2배의 크기를 갖는다.



Hotspot JVM 에서는 eden 영역에 객체를 빠르게 할당시키기 위해 bump the pointer 방식을 사용한다. bump the pointer 방식은 eden 영역의 시작 주소를 가리키는 포인터를 두고, 객체를 할당할 때마다 포인터를 이동시키는 방식이다. 따라서 새로운 객체를 할당시킬 공간을 탐색하기 위해 시간을 소용하지 않고 마지막으로 할당된 객체가 가리키고 있는 pointer를 이용하여 다음공간에 바로 할당을 하개된다.

멀티쓰레드 환경에서는 객체 할당에 있어 동기화 문제가 발생할 수 있기 때문에 lock 관리를 해주어야한다. 하지만 이는 성능상의 이슈로 이어질 수 있다. 이를 해결하기 위해 Hotspot JVM 에서는 thread-local allocation buffer(TLAB) 를 사용한다. TLAB 는 각각 쓰레드마다 eden 영역의 객체를 할당하기 위한 주소를 부여해주게 되고 이를 통해 동기화 작업 필요 없이 객체를 할당할 수 있게 된다.
728x90
반응형
복사했습니다!