Skip to content

6주차 pr입니다. #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: jivebreaddev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions ch06/박시창.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# 6. 가비지 수집 기초
- 시스템에 있는 모든 객체의 수명을 몰라도 런타임이 객체를 추적해서 쓸모없는 객체를 제거한다.
- GC 구현 원칙
- 모든 가비지 수집
- 살아있는 객체 제거 X (SEG FAULT)
## 6.1 마크 앤 스윕
- 마크 앤 스윕
- 할당 리스트를 순회 하면서 마크 비트 지운다.
- GC 루트부터 살아 있는 객체 식별
- 객체마다 마크 비트 셋업
- 마크 비트 없는 객체는
- 힙에서 메모리 회수
- 할당 리스트에서 객체 삭제
- 라이브 객체 그래프 (dfs 로 객체들 식별)
- `jmap -histo` 하면 객체별 heap 상태를 볼 수 있습니다.
### 6.1.1 가비지 수집 용어
- STW (STOP THE WORLD)
- 동시
- 병렬
- 정확
- 보수
- 이동
- 압착(COMPACT)
- 방출

## 6.2 핫스팟 런타임 개요
- JAVA는 기본형, 레퍼런스로 CALL BY VALUE 한다.(힙에 있는 객체의 주소)

### 6.2.1 객체를 런타임에 표현하는 방법
- OOP라는 구조체를 사용해서 객체를 표현합니다.
- Mark 워드
- Klass 워드
- LENGTH
- 32비트 여백
- OOP 상속 구조
- instanceOop
- methodOop
- arrayOop
- symbolOop
- klassOop
- markOop
### 6.2.2 GC 루트 및 아레나
- GC 루트는 메모리의 고정점으로 메모리 풀 외부에서 내부를 가리키는 포인터입니다.
- 내부 포인터와 외부 포인터가 있습니다.
- GC 루트의 종류
- 스택 프래임
- JNI
- 레지스터
- 전역 객체
- 클래스의 메타데이터
- 핫스팟 GC는 아레나라는 메모리 영역에서 일어납니다.
- 핫스팟은 자바 힙을 관리할 떄 시스템 콜을 하지 않습니다.
- 핫스팟은 유저공간 코드에서 힙크기를 관리해서 측정값을 확인해서 성능 문제를 확인 할 수 있습니다.
## 6.3 할당과 수명
- 할당률
- 일정 기간 새로 생성된 객체가 사용한 메모리 량입니다. (JVM이 기록X 쉽게 측정가능)
- 객체 수명
- 제대로 측정하기 어렵다.
### 6.3.1 약한 세대별 가설
- 객체 수명은 BINOMIAL DIST 를 따릅니다.
- 대부분의 객체는 짧은 시간을 살아 있고 다른 객체들은 수명이 훨씬길다.
- 핫스팟은 지표를 모읍니다.
- GENERATION COUNT(GC 통과 횟수)
- EDEN (YOUNG)
- OLD, TENURED(OLD)
- 늙은 객체가 젊은 객체를 참조하는일은 거의 없다.
- 카드 테이블이라는 구조에 늙은 객체가 젊은 객체를 참조하는 정보를 기록합니다.
- 늙은 객체의 o 에 있는 참조 형 필드값이 바뀌면 해당 엔트리를 더티 마킹합니다.

## 6.4 핫스팟 JVM 의 가비지 수집
- 자바는 OS를 이용해 동적으로 메모리를 관리하지 않습니다.
- 프로세스 시작 -> JVM 메모리 할당 -> 단일 메모리풀 관리
- 방출 -> 수집기가 객체들을 에덴 -> 에덴 -> 테뉴어로 이동시킴
-
### 6.4.1 스레드 로컬 할당
- JVM은 성능을 강화하여 에덴을 관리
- 여러 버퍼로 나눠서 각 애플리케이션 스레드가 새객체를 할당하는 구역으로 배포
- 각 스레드가 스레드 로컬 할당 버퍼(TLAB)을 받게됨 (동적 할당)
- 스레드가 버퍼를 다 채우면 JVM은 새 에덴 영역을 가르키는 포인터를 내줍니다.

### 6.4.2 방출형 수집
- 장수하지 못한 객체를 임시 수용소에 담자
- 테뉴어드 세대를 어지립히지 않고 풀 GC 발생 빈도 줄이기
- 수집기가 라이브 반구를 수집할 때, 객체들은 다른 반구로 압착시켜 옮기고 수집된 반구는 비워서 재사용
- 절반의 공간은 항상 완전히 비운다.
- 핫스팟에서 영 힙의 반구부를 서바이버 공간이라고 합니다.
- VISUAL gc 플러긴을 사용하면 gc 로그를 확인할 수 있습니다.

## 6.5 병렬 수집기
- JVM 디폴트 가비지 수집기는 병렬 수집기입니다.
- 처리율에 최적화 되어 있습니다.
- 영 GC, 풀 GC 모두 풀 STW를 일으팁니다.

- 병렬 수집기 종류
- Parallel GC
- ParallelOld GC
- 영세대 수집은 가장 흔한 가비지 수집 형태입니다.
- 스레드가 에덴에 객체를 할당하려는데 자신이 할당받은 TLAB 공간이 부족하면 영세대 수집을 발생시킵니다.
- JVM은 그떄 할수없이 STW 합니다.
- 스레드가 중단되면 핫스팟은 영세대를 뒤져서 가비지 아닌 개게를 골라냅니다.
- Parallel GC는 살아남은 객체를 현재 비어있는 서바이버 공간으로 모두 방출한후, 세대 카운트를 늘려 한차례 이동했음을 기록합니다.
- 에덴과 객체를 방출 시킨 서바이버 공간을 재사용가능한 빈 공간으로 표시하고 TLAB을 스레드에 배포합니다.
- 살아있는 객체만 건드려서 약한 세대별 가설을 활용
- STW 중단시간을 조금이라도 단축해서 효율적으로 수집하겠다는 의도
### 6.5.2 올드 세대 병렬 수집
- 하나의 연속된 메모리 공간에서 압착하는 수집기
- 아주 효율적이고 메모리 단편화가 일어날 일도 없다.
- 올드 공간은 크게 눈에 띄는 변화가 없습니다.
- ParallelOld GC는 하나의 연속된 메모리 공간에서 압착하는 수집기이비다.
- 메모리 단편화 안일어난다. 효율적이다.

### 6.5.3 병렬 수집기의 한계
- 풀 STW 유발한다.
- 영 수집은 살아있는 객체에 STW 시간이 비례한다 10ms
- 올드 수집은 stw 시간이 힙크기에 비례
- 손쉬운 스레드 생성이 자바의 강력한 장점 하지만 새로운 실행 스택들이 gc 루트의 원천이라서 gc가 복잡해진다.

## 6.6 할당의 역할
- 유입된 메모리 할당 요청을 수용하기에 메모리가 부족할 때 작동해서 필요한 만큼 메모리 공급
- 힙 메모리 공간이 꽉채워져 더이상 객체를 생성할 공간이 없을 대 일어난다. (불규칙함)
- gc 가 발생하면 모든 애플리케이션 멈춤
- visual vm으로 메모리 사용패턴을 잘 보면 힙사용률이 톱니바퀴로 나타나게 된다.
- 할당률이 너무 높음 -> 조기승격하게됨
- 튜닝 포인트가 된다.


158 changes: 157 additions & 1 deletion ch07/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,157 @@
# Ch7. 가비지 수집 고급
# 7. 가비지 수집 고급
- 현대 자바의 가비지 수집 이론
- 다양한 수집기들의 선정하는 배경
- 각종 수집기들의 특성


## 7.1 트레이드오프와 탈착형 수집기
- 코드 변경없이 탈착가능하다.
- 고려 항목들
- 중단시간 (제일큰 관심사)
- 처리율 (런타임 대비 GC 시간 %)
- 중단 빈도 (수집기 때문에 얼마나 자주 멈추냐)
- 회수 효율 (GC 사이클당 얼마나 많은 가비지 수집되는가?)
- 중단 일관성(중단시간이 고르냐?)
- 예
- 배치처리 시스템은 중단 기간보다 처리율이 더 큰 영향을 미친다.
- CPU 효율 및 처리율 우수한 GC를 사용해야한다.
## 7.2 동시 GC 이론
- 문제: 메모리 할당이 불확정성을 유발하므로 언제 끼어들지 확정적이지 않다.
- 최신 GC는 해당 문제를 해결하려고 시도한다.
- 동시 수집기를 써서 스레드 실행 도중 수집에 필요한 작업 일부를 수행한다.
### 7.2.1 JVM 세이프 포인트
- STW 가비지 수집을 하려면 애플리케이션 스레드를 모두 중단시켜야합니다.
- JVM은 스레드마다 SAFE POINT를 둡니다.
- GC 스레드가 OS에게 무조건 중단시켜달라고 요청할 수 없기 때문에, 애플리케이션 스레드는 반드시 서로 공조해야합니다.
- JVM은 강제로 스레드를 세이프포인트 상태로 바꿀 수 없다.
- JVM은 스레드가 세이프 포인트 상태에서 벗어나지 못하게 할 수 있다.
- JVM이 중단 하는 방법
- 1. JVM이 전역 세이프포인트 시간 플래그를 세팅한다.
- 2. 각 애플리케이션 스레드는 폴링 하면서 이 플래그가 세팅됐는지 확인한다.
- 3. 애플리케이션 스레드는 일단 멈췄다가 다시 깨어날때까지 대기한다.
- 일반 애플리케이션 스레드는 이런 식으로 바이트 코드 2개 실행할때마다 체크하게 된다.
### 7.2.2 삼색 마킹
- 알고리즘 동작원리
- GC루트를 회색 표시한다.
- 다른 객체는 모두 흰색 표시한다.
- 마킹 스레드가 임의의 회색 노드로 이동한다.
- 마킹 스레드가 흰색 표시된 자식 노드가 있는 노드를 만나면, 먼저 회색 표시한후 해당 노드를 검은색으로 표시한다.
- 회색 노드가 하나도 남지 않을때까지 위 과정을 되풀이한다.
- 검은색 객체는 접근 가능한것으로 살아남는다.
- 흰색객체는 수집대상이된다.
- 동시 수집 (스냅샷뜨기)
- 수집 사이클 시작할때, 할당된 객체는 라이브 객체로 간주한다.
- 단점
- 변경자 스레드가 수집하는 도중에 검은색 상태, 수집을 안하는 동안 흰색 상태로 객체 생성
- 라이브 객체가 수집되는 현상이 생길 수 도 있다.
- 업데이트시에 쓰기 배리어를 이용해서 마킹 사이클 동안 삼색을 그대로 유지합니다.
- `동시 마킹 도중에 검은색 객체 노드가 흰색 객체노드를 가리킬 수 없다.`
- 모든 변경사항을 미리 큐에 넣어두고 MAIN 이 끝나면 FIXUP에 바로잡는 경우도 있습니다.

## 7.3 CMS
- CMS 수집기는 중단시간을 아주 짧게하려고 설계된 TENURED 공간 전용 수집기입니다.
- 중단 시간을 최소화 하기 위해 스레드 실행중에 가급적 많은 일을 합니다.
- 마킹은 삼색 마킹
- 레코드 FIXUP
- 초기 마킹 (STW) GC루트 얻음
- 동시 마킹 | 삼색 마킹 진행
- 동시 사전 정리
- 재마킹 (STW)
- 동시 스윕
- 동시 리셋
- 효과
- 애플리케이션이 오래 멈추지 않는다.
- 단일 풀 GC 사이클 시간이 더길다.
- CMS GC 사이클동안 처리율 감소한다.
- GC가 객체를 추적하므로 메모리 사용 증가한다.
- GC 수행에 훨씬 더 많은 CPU 시간이 필요하다.
- CMS는 힙을 압착하지 않아서 테뉴어드 영역은 단편화된다.
- 느린 GC로 조기승격이 많이일어나 TENURED 공간 부족이 생긴다
- 동시 모드 실패로 불린다.
- 75 % 점유 이상시에 CMS 가 수집을 하는게 옵션으로 잡혀있다.
- 힙 단편화가 발생해서 그럴수도있다.
- 스위퍼 스레드로 여유 공간을 뭄치는 역할을 한다.
## 7.4 G1
- CMS와 스타일이 다른 수집기입니다.
- 특징
- CMS 보다 튜닝이 쉽다.
- 조기 승격에 덜 취약하다.
- 대용량 힙에서 확장성이 우수하다.
- 풀 STW 수집을 없앨수 있다.
- G1 힙 레이아웃 및 영역
- G1 힙은 영역으로 구성됩니다
- 영역은 디폴트 크기가 1MB
- 영역을 이용하면 세대를 연속적으로 배치할 필요 없습니다.
- 수집기가 매번 전체 가비지 수집 할 필요 없다.
- G1 알고리즘 설계
- 동시 마킹 단계를 이용한다.
- 방출 수집기
- 통계적으로 압착한다.
- TLAB 할당, 서바이버 공간 방출, 테뉴어드 승격 은 개념 같다.
- 차이점
- 영 세대의 크기는 전체 중단 시간 목표에 따라 조정된다.
- `올드 객체가 영객체를 참조하는일은 거의 없다.`
- G1 에서는 RSET이라는 장치로 영역을 추적합니다.
- RSET은 영역별로 하나씩 영역 내부를 참조하는 레퍼런스를 관리하기 위한 장치입니다.
- 전체 힙을 다 뒤질 필요없이 RSET만 꺼내보면됩니다.
- RSET은 부유 가비지 라는 GC 문제를 해결하는데 유용합니다.
- 전역적으로 LIVE 이지만 사용한 루트 세트에 따라 범위가 제한적인 로컬 마킹상에서 살아있는 객체로 잘못 인식된다.
- G1 단계
- 초기 마킹 (STW) 서바이버 영역에서 올드세대 레퍼런스 찾기 그다음 영 GC 탐색
- 동시 루트 탐색
- 동시 마킹
- 재마킹(STW)
- 정리(STW) 어카운팅, RSET의 씻기

## 7.5 셰난도아
- 주목표는 중단시간 단축
- 동시 압착을한다.
- 단계
- 초기마킹(STW)
- 동시마킹
- 최종마킹(STW)
- 동시압착
- 브룩스 포인터라고 객체가 재배치 됐는지 표기하는 포인터가 생깁니다.
- 해당 포인터가 있으면 새 OOP 위치를 참조하도록 수정합니다.
- 동시 압착 메커니즘
- 객체를 TLAB로 복사한다.
- CAS로 브룩스 포인터가 추측성 사본을 가리키도록 수정한다.
- 이 작업이 성공하면 압착스레드가 승리 이후 모든 버전은 브룩스 포인터를 경유한다.
- 실패하면 압착스레드가 실패한것으로 추측성 사본을 원상복구하고 승리한 스레드가 남긴 브룩스 포인터를 따라간다.
- 해당 수집기는 레드햇 페도라 같은 배포판에 실려있다.
- 중단시간 개짧네;;
## 7.6 C4
- 오라클 상용 솔루션
- 동시 압착 알고리즘 사용하는데 객체 헤더를 쓴다.
- 로드값을 자가치유 베리어로 로딩이 끝나면 객체 위치를 직접 가리키게 만들자.
- 단계
- 마킹
- 재배치
- 재매핑
- 영객체 + 올드 객체
- 동시 수집기 튜닝시 수집기가 백투백모드로 실행된다.
## 7.7 밸런스드
- 4GB 이상의 힙에 맞게 설계됨
- 대용량 힙에서 중단시간 길어지는 현상 개선
- 중단 시간이 최악일 경우 최소화
- IBM 에서 부분 가비지 수집으로 에덴이 꽉차면 수집진행함
- 나이가 많은 영역은 필요하면 수집하게됩니다. (G1 도 MIXED COLLECTION 함)
- 전역 가비지 수집도 있다.
- 객체 헤더는 클래스 슬롯이라고 불린다.
- 어레이릿이라고 여러 영역에 걸쳐서 할당할 수 있따.
- 전체 GC 시간은 더걸리지만 평균 중단시간은 줄어든다.
- 압착 혹은 stw 수집의 경우의 수가 줄어든다.

## 7.8 레거시 핫스팟 수집기
- Serial && Serial Old
- Parallel Old GC와 동작원리 동일
- 증분 CMS
- 동시 수집
- G1에 영향
- 엡실론
- 아무일도 안하는 수집기
- 테스트 및 벤치마킹
- 회귀 테스트
- 할당률이 0인 애플리케이션 혹은 라이브러리 코드의 테스트
- JMH테스트 용
## 7.9 마치며
1 change: 1 addition & 0 deletions ch07/박시창.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading