(Java 소스 분석) Java Collection 작동원리

NAVER D2 글: http://d2.naver.com/helloworld/1329


*가비지 컬렉션 과정

'stop-the-world' : GC를 실행하기 위해 JVM 애플리케이션이 실행을 멈추는 것이다.
가비지컬렉션이 시작되면 Garbage Collection을 담당하는 쓰레드를 제외하고 모든 쓰레드가 정지한다. GC작업을 완료한 이후에 중단했던 작업을 다시 시작한다.
어떤 GC알고리즘을 사용하더라도 이 stop-the-world는 발생한다. 대개의 경우 GC튜닝은 이 stop-the-world시간을 줄이는 것이다.


Java는 프로그램 코드에서 메모리를 명시적으로 지정하여 해제하지 않는다. 가끔 명시적으로 해제하려고 해당 객체를 null로 지정하거나 System.gc() 메서드를 호출하는 개발자가 있다. null로 지정하는 것은 큰 문제가 안 되지만, System.gc() 메서드를 호출하는 것은 시스템의 성능에 매우 큰 영향을 끼치므로 System.gc() 메서드는 절대로 사용하면 안 된다(다행히도 NHN에서 System.gc() 메서드를 호출하는 개발자를 보진 못했다).

*가비지 컬렉터는 두 가지 가설에 의해 만들어졌다.

  • 대부분의 객체는 금방 접근 불가능한 상태가 된다.
  • 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.



*Old영역에 있는 객체가 Young영역의 객체를 참조하는 경우가 있을때에는 어떻게 처리 될까? 이런경우를 처리하기 위해서는 Old영역에는 512바이트의 덩어리 (chunk)로 되어있는 카드 테이블(card table)이 존재한다.

카드 테이블에는 Old영역에 있는 객체가 Young영역의 객체를 참조할 때마다 정보가 표시된다. Young영역의 GC를 실행할 떄에는 Old영역에 있는 모든 객체의 참조를 확인하지 않고, 이 카드테이블만 뒤져서 GC대상인지 식별한다.


카드 테이블은 write barrier를 사용하여 관리한다. write barrier는 Minor GC를 빠르게 할 수 있도록 하는 장치이다. write barrirer때문에 약간의 오버헤드는 발생하지만 전반적인 GC 시간은 줄어들게 된다.





Old 영역에 대한 GC


Old영역은 기본적으로 데이터가 가득 차면 GC를 실행한다. 



Old 영역은 기본적으로 데이터가 가득 차면 GC를 실행한다. GC 방식에 따라서 처리 절차가 달라지므로, 어떤 GC 방식이 있는지 살펴보면 이해가 쉬울 것이다. GC 방식은 JDK 7을 기준으로 5가지 방식이 있다.
  • Serial GC
  • Parallel GC
  • Parallel Old GC(Parallel Compacting GC)
  • Concurrent Mark & Sweep GC(이하 CMS)
  • G1(Garbage First) GC

이 중에서 운영 서버에서 절대 사용하면 안 되는 방식이 Serial GC다. Serial GC는 데스크톱의 CPU 코어가 하나만 있을 때 사용하기 위해서 만든 방식이다. Serial GC를 사용하면 애플리케이션의 성능이 많이 떨어진다.
그럼 각 GC 방식에 대해서 살펴보자.








댓글

이 블로그의 인기 게시물

(ElasticSearch) 결과에서 순서 정렬

(네트워크)폴링방식 vs 롱 폴링방식

(18장) WebSocekt과 STOMP를 사용하여 메시징하기