Java, GC, 가비지컬렉터의 작동 방식

infoqoch·2021년 4월 26일
1

JAVA

목록 보기
9/9

GC란?

  • GC란 가비지 컬렉션의 약자이며, JVM의 Heap영역에서 사용하지 않는 객체를 삭제하는 프로세스를 말한다.

GC의 대상은?

  • 참조되지 않은객체 (UnReachable)이 수거 대상입니다.

heap 영역은?

  • heap 영역은 Young Generation과 Old Generation으로 나뉜다. Young은 Eden 영역과 Survivor 2개영역으로 총 3개의 영역으로 나뉜다.
  • 객체가 생성할 때 그 객체는 Eden에 생성된다.

참조하지 않은 객체를 어떻게 구별하는가? Mark-Sweep 알고리즘과 Minor GC

  • 객체에는 mark-bit 하나씩 할당된다. 프로세스가 작동할 때, 사용된 객체의 mark-bit은 1이 된다. mark-bit의 경우 일종의 chain으로 작동하여 참조하는 객체는 다른 객체를 불러오며 동시에 mark-bit을 1로 만든다.
  • 새로 생성된 객체는 Eden에 저장된다. Eden에 꽉 차면 Minor GC가 작동한다. Minor GC는 heap영역의 1번지부터 마지막까지 하나씩 탐색한다. 탐색 과정에서 1인 것은 0으로 만들고 0인 것은 제거한다.
  • 다시 프로세스가 수행되어 참조하는 객체는 0에서 1이 된다.

살아남은 객체는 어떻게 작동하는가? Young Generation

  • 살아남은 객체는 서바이버 1로 이동한다.
  • 에덴이 꽉 차면 minor GC가 작동한다. 서바이버 1과 에덴에서 살아남은 객체가 서바이버 2로 이동하며, compact된다.
  • 에덴이 꽉차면 다시 minor GC가 작동한다. 에덴과 서바이버 2에서 살아남은 객체가 서바이버1로 이동한다.
  • 살아남은 객체는 age bit이 1씩 올라간다. age bit의 한계치(Tenuring Threshold) 이상 반복할 경우 Old영역으로 이동한다.

Old Generation, Major GC

  • Young Generation에서 살아남은 객체는 Old Generation으로 승급Promption한다.
  • 만약 Old Generation이 가득차면, Major GC(OutOfMemory, Stop-the-world)가 일어난다. JVM이 멈춘다.

GC 알고리즘들

  • Serial GC
    • 스레드가 하나이다.
    • Mark - Compact Collection 알고리즘 : Compact 기능이 추가. Linked-list로 연결되어 free가 된 공간의 파편화를 없앰.
  • Parallel GC
    • Java 8 기본값
    • 스레드가 여러개이다.
    • GC의 작동을 빠르게 Stop-the-world의 속도를 줄임
  • G1 GC
    • Java 9 기본값
    • Heap을 일정 크기의 Region으로 나눔.
    • Region의 참조 수준에 따라 Eden, Survivor, Old Generation으로 구분.
    • Minor GC가 모든 주소를 참조하지 않으므로 탐색 속도가 빠름

JVM에서 메모리 누수가 발생할까?

  • JVM에서도 메모리 누수가 발생할 수 있다. GC는 참조하지 않는 Unreachable한 객체를 제거 대상으로 간주하기 때문에 사용은 하지 않지만 계속해서 참조를 하는 경우가 있다면 메모리 누수가 발생할 수 있다.

GC를 개발자가 세팅할 수 있을까?

  • GC는 System.gc() 메소드를 통해 개발자가 의도적으로 실행이 가능하지만 권장하지 않는다. Stop-the-world 가 발생할 수 있어 시스템의 성능을 오히려 저하시킬 수 있다.
  • GC, 정확하게 JVM은 자바 버전이 올라감에 따라 성능이 발전한다. 그러므로 자바의 높은 버전을 사용하는 것을 추천한다.
  • 사용자는 필요에 따라 GC 알고리즘, Tenuring Threshold을 변경할 수 있다. 힙 메모리의 최소 용량과 최대 용량을 설정할 수 있다.
  • 첨언하자면, 이번에 GC를 공부하면서 인텔리제이 VM 세팅이 무엇인지 이해할 수 있었다. 최적화라고 해서 그냥 따라했었는데. 내가 설정한 힙 메모리 최솟값과 최댓값은 아래와 같다. 하고 나서 정말 빨라졌다! 이클립스, 인텔리제이 관계 없이 모두 변경하는 것 추천한다. (참고로 나는 램이 16기가이다)
	-Xms2g
	-Xmx6g

참고

profile
JAVA web developer

0개의 댓글