[Java] 가비지 컬렉터

soohee·2023년 3월 19일
2

Java

목록 보기
1/3
post-thumbnail

🥴 가비지 컬렉터란?

JVM의 Heap영역에서 동적으로 할당했던 메모리 영역 중 필요 없게 된 메모리 영역을 주기적으로 삭제하는 프로게스를 관리해주는 담당자.

🫡 가비지 컬렉션의 대상

  • 객체가 NULL인 경우
  • 블럭 실행 종료 후, 해당 블럭 안에서 생성되었던 (이제 사용되지 않는) 객체들
  • 부모 객체가 NULL인데, 그것을 참조하는 자식 객체

이정도는 흔히 볼 수 있었던 내용이다. 그렇다면 좀 더 자세하게 가비지 컬렉터가 어떻게 동작되는지 파헤쳐보았다.

먼저, 궁금한 점은 두 가지이다.

  1. 가비지 컬렉터의 동작원리
  2. 가비지 컬렉션은 장점만 있는가?

📙 가비지 컬렉터의 동작원리

🍊 간단 동작원리

  1. GC ROOT라고 불리우는 객체부터 시작해서, 참조를 찾아다니게 된다.
  2. 이때, 어떤 객체가 유효한 참조를 가지고 있다면 접근 가능한 객체로 판단되어 정리되지 않는다.
  3. 그러나, 참조를 가지고 있지 않다면, 접근 불가능한 객체로 판단되어 가비지 컬렉터에 의해 정리된다.
  4. 그리고, 이 객체를 담고 있었던 메모리는 재사용 될 수 있다.

🎃 그렇다면 GC ROOT가 될 수 있는 객체는?

  • 실행중인 쓰레드 (Active Thread)
  • 정적 변수 (Static Variable)
  • 로컬 변수 (Local Variable)
  • JNI 레퍼런스 (JNI Reference)

🪐 예시를 들어보자

아래와 같은 메모리 공간이 있다.

  1. String str = new String("Hello") 라는 코드가 작성되면, Stack 영역에는 str이라는 변수가, Heap 영역에는 new String("Hello")라는 오브젝트가 생성된다.

  1. str이 String오브젝트를 참조한다.
    여기서의 GC Root는 str이고, 가비지 컬렉터가 사용되면 GC root인 str이 참조하는 메모리인 new String("Hello")를 마크한다.

  1. 이후 메서드가 리턴하면서 str이라는 변수가 사라지면 new String("Hello")은 아무도 참조하지 않는다.

  1. 다음 가비지 컬렉터 실행시, 해당 오브젝트는 sweep 된다.

📗 가비지 컬렉션의 단점은?

  1. 개발자가 메모리가 언제 해제되는지 정확하게 알 수 없다.
  2. 가비지 컬렉션(GC)이 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드가 발생한다.

참고) Mark and Sweep 알고리즘

Mark And Sweep 알고리즘은 가비지 컬렉션이 동작하는 원리로 루트에서부터 해당 객체에 접근 가능한지에 대한 여부를 메모리 해제의 기준으로 삼습니다. Mark And Sweep은 위의 그림과 같이 총 3가지 과정으로 나뉘게 됩니다.

  • Mark 과정 : 먼저 Root로부터 그래프 순회를 통해 연결된 객체들을 찾아내는 방식으로, 할당받은 메모리중 1비트를 남겨 직/간접적인 참조를 하는지 하지않는는지 표시합니다.
  • Sweep 과정 : 참조하고 있지 않은 객체 즉 Unreachable 객체들을 Heap에서 제거합니다.
  • Compact 과정 : Sweep 후에 분산된 객체들을 Heap의 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축합니다. (가비지 컬렉터 종류에 따라 하지 않는 경우도 있음)
profile
🐻‍❄️

2개의 댓글

comment-user-thumbnail
2023년 3월 20일

수동적으로 가비지컬렉터를 다루는 방법은 없나요?
좋은 글 감사합니다

1개의 답글