[JVM] 객체를 언제, 어떻게 표시할 것인가?

2026. 1. 5. 16:30·CS/JVM

JVM 내에서 도달 가능성 분석 알고리즘을 다시 정의해보자면

 

https://dev-dx2d2y-log.tistory.com/165

 

[JVM] OopMap으로 참조체인 내 속한 객체 찾기

루트 노드 열거GC를 시작하려할 때 가장 기본이되는 것이 GC루트를 기준으로 '도달 가능성 알고리즘'을 실행시키는 것이다.루트 노드 열거는 도달 가능성 알고리즘을 구현하기 위해서 GC 루트집

dev-dx2d2y-log.tistory.com

도달 가능성 분석 알고리즘을 사용하기 위해서는 GC루트들을 찾고 (루트노드열거), OopMap을 통해서 그 참조체인의 관계까지 알아두어야한다. 이 과정에서 스레드는 모두 정지해있어야한다.

 

그 중에서 참조체인을 찾는 과정에 집중해보자면, 마크-스윕, 마크-카피, 마크-컴팩트 알고리즘 등에서도 알 수 있듯이 대부분의 가비지컬렉터에는 '표시' 단계가 있다. 이 '표시' 단계에서 소요되는 시간을 줄인다면 가비지컬렉터의 성능을 향상시킬 수 있다. 이번에는 '표시하는 방법'에 대해 알아보려한다.


삼색표시(tri-color marking) 기법

참조체인을 따라 조우하는 객체들을 '방문한 객체인가?'라는 조건에 따라서 색을 칠한다.

 

- 흰색: 가비지컬렉터가 조우한 적 없는 객체. 가장 처음 GC를 시작할 때에는 모든 객체들이 흰색이다.

- 검정색: 가비지컬렉터가 확인한 객체이며, 이 객체에서 가리키는 모든 참조를 확인했다. 만약 다른 곳에서 이 객체를 참조하고 있다면 이 객체를 확인하지 않아도 된다. 그렇기 때문에 검정색 객체가 흰색 객체를 직접 가리킬 수 없다. (논리적 모순)

- 회색: 가비지컬렉터가 확인했지만 이 객체가 참조 중인 객체 중 스캔을 완료하지 않은 참조가 존재한다.

 

세 가지로 나눌 수 있다. 그래서 객체들을 스캔하는 과정은 흰색 객체들이 있다가 회색으로 변한 후, 검정색으로 변하는 파도와 같은 과정과 비슷하다. 이 과정에서 사용자스레드들은 멈춰있어야한다.


동시성 문제

https://dev-dx2d2y-log.tistory.com/170

 

[JVM] JVM 내에서 카드테이블과 사전장벽, 사후장벽이란?

기억집합 (카드테이블)https://dev-dx2d2y-log.tistory.com/162 [JVM] GC의 객체회수과정은 어떻게 일어나는가? - 마크-스윕, 마크-카피, 마크-컴팩트https://dev-dx2d2y-log.tistory.com/163 [Java] JVM 끝까지 파헤치기 독

dev-dx2d2y-log.tistory.com

하지만 이전에 사전장벽과 사후장벽에서 다뤘듯이, 현대의 GC는 모든 사용자 스레드를 멈춰놓고 실행되지 않는다. 참조체인에서 색을 칠해가는 과정에서 갑자기 사용자 스레드에서 참조관계를 변경한다면 어떻게될까? 가능한 문제의 경우는 두 가지.

 

1. 죽은 객체를 살았다고 표시하기

컬렉터가 검은색으로 표시하고 간 객체의 참조가 참조해제되는 경우에 일어날 수 있다. 문제이긴하지만 다음번 GC 때 회수하면 되므로 그렇게 큰 문제는 아니다.

 

2. 살아있는 객체를 죽었다고 표시하기

흰색 객체에서 참조 중이거나 회색 객체가 참조 중인 객체들 중에서 컬렉터가 확인하지 않은 객체가 갑자기 참조해제되고 검은색으로 표시된 객체가 해제된 객체를 참조하기 시작했다면? 컬렉터는 검정색 객체를 재확인하지 않으므로 해당 객체가 참조되지 않았다고 판단하여 메모리를 회수할 것이다. 1번과 달리 이 문제는 매우 심각한 문제이므로 좌시해서는 안된다.

 

1994년 윌슨은 2번과 같은 객체 사라짐 문제는 다음 두 조건을 동시에 만족할 때 발생한다고 한다.

 

1. 사용자 스레드에서 검은색 객체가 흰색 객체를 참조하도록 함

2. 사용자 스레드가 회색 객체에서 흰색 객체로의 직간접적인 참조를 삭제함

 

위의 예시에서도,

1. 흰색 객체가 참조 중인 객체가 참조해제되고 검은색 객체가 참조 해제된 객체를 참조하기 시작함

흰색 객체는 회색객체과 흰색객체들에 의해 참조되고 있으므로 2번을 만족, 1번도 만족.

 

2. 회색 객체가 참조 중인 객체들 중에서 컬렉터가 확인하지 않은 객체가 참조해제되고 검은색으로 표시된 객체가 참조 해제된 객체를 참조하기 시작함

이 경우도 회색객체가 직접참조하는 객체에서 1번이 이루어졌으므로 1번과 2번이 만족한다.

 

 

즉, 저 두 가지의 상황이 "동시에" 발생해야 동시 스캔 중 객체 사라짐 문제가 발생한다. 해결법으로는 저 두 조건이 동시에 일어나지 않게하는 것. 따라서 해결법도 두 개다.


1. 첫 번째 조건 깨트리기 - 증분 업데이트

회색객체가 직간접적으로 참조하던 객체의 참조가 해제되고 (2번 조건 발생), 검은색 객체가 참조해제된 객체를 참조하게 된 경우, 새로이 참조가 발생하는 검은색 객체를 따로 기록해두어 메모리 회수 대상으로 삼지 않는다. 스캔이 끝나면 기록해 둔 검은색 객체들을 GC루트로하여 다시 한 번 스캔한다.


2. 두 번째 조건 깨트리기 - 시작 단계 스냅숏(snapshot at the beginning)

회색객체가 직간접적으로 참조하던 객체의 참조가 해제될 때, 회색 객체가 흰색 객체의 참조를 끊으려함을 기록한다. 스캔이 끝나면 기록해 둔 참조가 끊어진 객체들을 메모리 회수대상에서 제외한다.
이 방식이 기억테이블의 사전참조와 유사한데.. GC시작 후 객체 참조가 해제되었을 때 이런방식으로 참조를 기록한 후에 다시 등록하는 것을 SATB (Snapshot At The Beginning) 방식이라 한다. 저번에 말한 사전참조가 등장한 이유에서 주구장창 나왔던 SATB 방식이 바로 이 방식.


위 방식들은 참조관계가 변하기 전이나 후에 특정한 동작을 수행하는, "쓰기 장벽"에 해당한다. 모든 컬렉터들은 위 두 가지 방식 중 하나의 쓰기장벽을 사용한다. 따라서 쓰기장벽의 분류기준을 통해서 보자면, 증분 업데이트는 해제된 객체를 기록하지 않으므로 사후장벽, 시작단계스냅숏은 해제된 객체를 기록하지 않으므로 사전장벽에 해당한다.

 

 

[JVM] JVM 내에서 카드테이블과 사전장벽, 사후장벽이란?

즉, 증분 업데이트를 사용하면 사후장벽의 단점을 그대로 겪는다고 봐도 무방하다. 다만, 증분 업데이트는 스캔이 끝난 후 검은색 객체들을 GC루트로 삼아서 다시 한 번 스캔하므로 "참조해제가 일어났다면 그 변경사항을 GC에게 실시간으로 알린다"와 비슷한 일이 벌어진다고 봐야한다.

 

그래서 증분 업데이트는 단독으로는 잘 사용되지 않는다. CMS GC가 증분 업데이트를 사용했지만, JDK9에서 Deprecated 되었고, JDK14에서 삭제되었다.

 

쓰기장벽할 때 간략하게 언급되었던 G1 컬렉터와, 셰넌도어 컬렉터는 시작단계스냅숏을 사용한다.

'CS > JVM' 카테고리의 다른 글

[JVM] JVM 끝까지 파헤치기 독서 #6 - 가비지컬렉션 심화탐구  (1) 2026.01.05
[JVM] JVM 내에서 카드테이블과 사전장벽, 사후장벽이란?  (1) 2026.01.01
[JVM] 가비지컬렉터는 어디에서 실행되어야하는가? - 안전지점(Safe Region)  (0) 2025.12.27
[JVM] OopMap으로 참조체인 내 속한 객체 찾기  (0) 2025.12.27
[JVM] JVM 끝까지 파헤치기 독서 #5 - 가비지 컬렉터의 알고리즘 이론  (0) 2025.12.26
'CS/JVM' 카테고리의 다른 글
  • [JVM] JVM 끝까지 파헤치기 독서 #6 - 가비지컬렉션 심화탐구
  • [JVM] JVM 내에서 카드테이블과 사전장벽, 사후장벽이란?
  • [JVM] 가비지컬렉터는 어디에서 실행되어야하는가? - 안전지점(Safe Region)
  • [JVM] OopMap으로 참조체인 내 속한 객체 찾기
Radiata
Radiata
개발을 합니다.
  • Radiata
    DDD
    Radiata
  • 전체
    오늘
    어제
    • 분류 전체보기 (211) N
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (59) N
        • JVM (12)
        • 백엔드 (20) N
        • 언어구현 (1)
        • 객체지향 (1)
        • 논리회로 (5)
        • 컴퓨터구조 (9)
        • 데이터베이스 (1)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (64)
        • Java | Kotlin (48)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (2)
      • 고찰 (24)
        • CEOS 23기 회고록 (2)
  • 블로그 메뉴

    • CS
    • 언어공부
    • 개인 프로젝트
    • 팀 프로젝트
    • 알고리즘
    • 고찰
    • 신년사
    • 컬러잇 개발블로그
  • 링크

    • 컬러잇 개발블로그
  • 공지사항

  • 인기 글

  • 태그

    144
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Radiata
[JVM] 객체를 언제, 어떻게 표시할 것인가?
상단으로

티스토리툴바