[Java Performance]Java 쓰레기 수 거 안내

이 시 리 즈 는 자바 Performance:The Definitive Guide 의 독서 노트 입 니 다.
개관
현재 JVM 에는 주로 4 개의 쓰레기 수 거 기(Garbage Collector)가 있 습 니 다.
직렬 회수 기(Serial Collector)는 주로 단일 핵 컴퓨터 에 사용 된다스루풋(병렬)회수 기(Throughput/Parallel Collector)동시 회수 기(Concurrent/CMS Collector)G1 회수 기그것들의 성능 특징 은 각각 다 르 기 때문에 구체 적 으로 다음 장 에서 소개 할 것 이다.그러나 이들 은 쓰레기 회수 에 관 한 기초 지식 을 설명 하기 위해 공 통 된 원리 와 개념 을 가지 고 있다.
한 마디 로 GC 의 임 무 는 더 이상 사용 되 지 않 는 대상 을 찾 아 사용 하 는 메모 리 를 방출 하 는 것 이다.일반적으로 JVM 은 더 이상 인용 되 지 않 는 대상 을 찾 아 회수 할 수 있다 고 생각 합 니 다.따라서 대상 의 모든 인용 은 하나의 계수 기 를 통 해 저장 된다 는 뜻 이기 도 하 다.그러나 이런 인용 계수 만 으로 는 부족 하 다.예 를 들 어 반복 적 으로 인용 되 는 경우 모든 대상 이 인용 되 지만 실제로 사용 되 지 는 않 는 다.
따라서 JVM 은 사용 되 지 않 은 대상 을 주기 적 으로 찾 아 회수 하고 사용 하 는 메모 리 를 방출 해 야 한다.그러나 방출 만 으로 는 부족 하 다.그러면 대량의 메모리 조각(Memory Fragmentation)을 가 져 올 수 있 기 때문에 JVM 은 메모리 에 있 는 다른 대상 에 게 위치(Compacting)를 다시 배치 하여 그 조각 들 을 제거 해 야 한다.
GC 의 실현 은 각기 다 르 고 세부 적 인 부분 이 많 지만 GC 의 성능 은 주로 상기 에서 언급 한 몇 가지 조작 에 달 려 있다.
사용 되 지 않 은 대상 을 검색 합 니 다그들 이 사용 하 는 메모 리 를 방출 합 니 다압축 더미(열 압축)GC 가 실 행 될 때 프로그램의 스 레 드 가 실행 되 지 않 으 면 일이 훨씬 간단 해 집 니 다.그러나 이것 은 불가능 합 니 다.자바 응용 은 보통 많은 스 레 드 를 사용 합 니 다.그러면 GC 가 이 과정 에 참여 할 때 모든 스 레 드 는 두 그룹 으로 나 눌 수 있 습 니 다.
응용 프로그램 스 레 드
GC 스 레 드GC 스 레 드 가 작 동 할 때 메모리 의 대상 을 조정 하기 때문에 이 대상 들 은 응용 프로그램 스 레 드 에 의 해 사용 되 기 때문에 GC 스 레 드 가 작 동 할 때 응용 프로그램 스 레 드 는 현재 작업 을 멈 춰 야 합 니 다.이러한 정 지 는 Stop-the-World 정지 라 고도 불 리 며 응용 프로그램의 성능 에 심각 한 영향 을 미 칠 수 있 으 므 로 GC 를 개선 할 때 이러한 정지 시간 을 줄 이 는 것 이 관건 이다.
세대 기반 쓰레기 수 거 기(Generational Garbage Collectors)
GC 의 실현 은 각기 다 르 지만 메모리 더 미 를 몇 세대 로 나 눌 것 이다.그것들 은 각각:
연로 대(Old/Tenured Generation)신세대(Young Generation)
Eden Space
Survivor Space

메모 리 를 분할 하 는 이 유 는 프로그램 이 실 행 될 때 특정한 시간 동안 많은 대상 이 생 성 되 고 사용 되 며 버 려 질 수 있 기 때 문 입 니 다.예 를 들 어:
sum = new BigDecimal(0);
for (StockPrice sp : prices.values()) {
    BigDecimal diff = sp.getClosingPrice().subtract(averagePrice);
    diff = diff.multiply(diff);
    sum = sum.add(diff);
}

BigDecimal 은 자바 에서 가 변 적 이지 않 은 형식(Immutable Class)이기 때문에 위의 모든 순환 에서 몇 개의 새로운 BigDecimal 대상 을 만들어 계산 을 완성 합 니 다.이들 대상 은 수명 주기 가 짧 아 1 차 순환 이 끝나 면 곧바로 GC 후보 재 활용 대상 이 된다.
이러한 행 위 는 자바 응용 에서 매우 보편적 이 며,새로 만 든 대상 은 먼저 신세대 메모리 영역 에 분 배 될 것 이다.신세대 메모리 영역 이 가득 차 면 GC 는 모든 프로그램의 스 레 드 를 중단 하고 신세대 영역 을 회수 하려 고 합 니 다.
사용 되 지 않 은 대상 의 메모리 가 방출 되 었 습 니 다아직 사용 중인 대상 은 다른 곳 으로 이동 합 니 다이 과정 은 마 이 너 GC 라 고 불 린 다.
이런 디자인 을 사용 하 는 두 가지 장점:
신 생 세 대 는 전체 메모리 구역 의 일부분 일 뿐 이 므 로 이 구역 만 처리 하 는 것 이 빠 르 고 응용 프로그램 에 미 치 는 영향 도 적 습 니 다(GC 작업 시 응용 프로그램의 일시 정지 로 이 어 질 수 있 기 때 문 입 니 다).그러나 이 로 인해 응용 프로그램 이 자주 중단 되 는 것 을 알 수 있 습 니 다.GC 가 더욱 빈번 해 졌 기 때문에 이 점 에 대해 서 는 뒷글 에서 토론 할 것 입 니 다
새로 생 긴 대상 은 신세대 지역 의 Eden Space 에 배 치 돼 신세대 의 대부분 을 차지 하기 때문이다.GC 가 이 지역 을 회수 할 때 대상 은 회수 되 거나 Survivor Space 로 이동 되 거나 Old Generation 으로 이동 하 는 것 은 GC 가 실 행 된 후에 Eden Space 가 비 워 지고 Compacting 의 절 차 를 절약 할 수 있다 는 것 을 보장 한다
모든 GC 알고리즘 은 신세대 메모리 영역 을 회수 할 때 모든 프로그램 스 레 드(Stop-the-World Pause)를 중단 합 니 다.
대상 이 Old Generation 으로 이동 하면 서 결국 이 구역 도 채 워 진다.이때 JVM 은 이 영역 을 회수 해 야 하 며 GC 알고리즘 에 따라 크게 다르다.가장 간단 한 알고리즘 은 모든 프로그램 스 레 드 를 중단 하고 회수 하 는 세 가지 절 차 를 완성 합 니 다.이 과정 은 Full GC 라 고 불 린 다.그것 은 보통 프로그램 이 더 오래 멈 추 게 할 것 이다.
다른 한편,사용 하지 않 는 대상 을 찾 는 과정 에서 응용 프로그램 스 레 드 를 멈 추 지 않 고 CMS 와 G1 회수 기 를 사용 하면 할 수 있 습 니 다.이것 도 그것들 이 병발 회수 기 라 고 불 리 는 원인 이다.이와 함께 이들 이 Old Generation 을 압축 할 때 사용 하 는 알고리즘 도 다르다.그러나 동시 회수 기 를 사용 하면 계산 과정 이 더욱 복잡 하기 때문에 더 많은 CPU 자원 을 소모 할 수 있다.어떤 장면 에 서 는 CMS 와 G1 도 응용 프로그램의 장시간 중단 을 초래 할 수 있 으 며,이 를 사용 할 때 이 를 피하 기 위해 서 는 조정 이 필요 하 다.
GC 에서 선택 한 조언 들
서버 프로그램:병렬 회수 기 또는 Throughput 회수 기일괄 처리 프로그램:CPU 자원 이 병목 이 아 닐 때 동시 회수 기 를 사용 합 니 다.그렇지 않 으 면 성능 이 떨 어 질 수 있 습 니 다총결산
모든 GC 알고리즘 은 메모리 더 미 를 Young Generation 과 Old Generation 으로 나 눕 니 다
모든 GC 알고리즘 은 Young Generation 을 회수 할 때 Stop-the-World 가 일시 정지 되 지만 Young Generation 을 회수 하 는 과정 은 매우 빠르다
GC 알고리즘
직렬 회수 기(시리 얼 가비지 컬렉터)
클 라 이언 트 급 컴퓨터(JVM 32 비트 를 사용 하 는 Windows 또는 단일 프로세서)에서 실 행 될 때 기본 으로 사용 되 는 회수 기 입 니 다.
이것 은 하나의 스 레 드 를 사용 하여 Heap 처 리 를 완성 합 니 다.Minor GC 든 Full GC 든 응용 프로그램의 중단 을 초래 할 수 있 습 니 다.풀 GC 에 서 는 올 드 제 너 레이 션 전 체 를 압축 한다.
사용 가능:-XX:+UseSerialGC 그것 을 사용 합 니 다.
스루풋 회수 기
서버 급 컴퓨터(다 핵 유 닉 스 와 64 비트 JVM 사용)의 기본 선택 입 니 다.
여러 스 레 드 를 사용 하여 Young Generation 을 회수 하기 때문에 Minor GC 의 속 도 는 직렬 회수 기 보다 빠르다.Old Generation 에 대해 서도 여러 스 레 드 를 이용 하여 회수 작업 을 할 수 있 습 니 다.이것 은 JDK 7u4 와 그 다음 버 전의 기본 동작 입 니 다.물론 JDK 7u4 이전에 도 통과 할 수 있다. 이 기능 을 사용 합 니 다.여러 스 레 드 를 사 용 했 기 때문에 병렬 회수 기 라 고도 불 린 다.
직렬 회수 기와 마찬가지 로 Minor GC 와 Full GC 에서 도 모든 프로그램 스 레 드 를 중단 하고 Full GC 에서 Old Generation 전 체 를 압축 합 니 다.
사용 하려 면 사용 하 십시오.
CMS 회수 기
CMS 수 거 기 는 Full GC 에서 직렬 및 스루풋 수 거 로 인 한 장시간 일시 정 지 를 해결 하기 위 한 것 입 니 다.CMS 수 거 기 는 Young Generation 을 회수 할 때 도 모든 애플 리 케 이 션 스 레 드 를 일시 정지 시 키 지만,다른 알고리즘 을 사용 해 Young Generation 을 수 거 합 니 다.
CMS 는 하나 이상 의 배경 스 레 드 를 사용 하여 Old Generation 을 주기 적 으로 스 캔 하여 사용 되 지 않 는 대상 을 회수 하기 때문에 프로그램 스 레 드 를 중단 할 필요 가 없습니다.그러나 백 스테이지 스 레 드 가 존재 하기 때문에 CMS 는 CPU 의 부 하 를 증가 시 키 고 백 스테이지 스 레 드 는 더 미 를 압축 하지 않 습 니 다.
사용 가능 한 CPU 자원 이 부족 하거나 메모리 에 조각 이 너무 많 을 때 CMS 는 직렬 회수 기,즉 모든 프로그램 스 레 드 를 중단 하고 쓰레기 수 거 를 실행 하여 메모리 압축 을 완성 하 는 데 도움 을 요청 합 니 다.마지막 으로 CMS 는 백 스테이지 스 레 드 를 시작 하여 원래 의 알고리즘 을 복원 합 니 다.
CMS 회수 기 를 사용 하면 사용:-XX:+UseParallelOldGC-XX:+UseParallelGC
G1 회수 기
G1 회수 기 는 주로 4GB 이상 의 메모리 가 쌓 인 응용 장면 을 대상 으로 하기 때문에 서버 측의 응용 에 더욱 적합 하 다.메모리 더 미 를 여러 영역 으로 나 누고 일부 영역 에는 Young Generation 이 포함 되 어 있 습 니 다.Young Generation 에 대한 수집 은 여전히 Stop-the-World Pause 가 존재 합 니 다.CMS 회수 기와 유사 하 며,몇몇 백 스테이지 스 레 드 를 사용 하여 회수 합 니 다.
다른 것 은 G1 이 메모 리 를 여러 구역 으로 나 누 었 기 때문에 Full GC 를 진행 할 때 한 구역 내의 대상 을 다른 구역 으로 이동 시 켜 청 소 를 완성 하 는 것 과 같 습 니 다.마치 Minor GC 에서 Eden Space 의 대상 을 Survivor Space 나 Old Generation 으로 이동 시 키 는 것 과 같 습 니 다.이렇게 하면 Compacting 의 절 차 를 줄 일 수 있 습 니 다.
마찬가지 로 G1 을 사용 하면 추가 적 인 CPU 부 하 를 가 져 올 수 있 습 니 다.사용 할 수 있 습 니 다-XX:+UseConcMarkSweepGC 사용 합 니 다.
명시 적 트리거 쓰레기 회수
먼저 결론 을 내 렸 다.정상 적 인 상황 에서 쓰레기 회수 작업 을 명시 적 으로 촉발 하 는 것 을 추천 하지 않 는 다.
프로그램 에서 호출 할 수 있 습 니 다.  -XX:+UseParNewGC  풀 GC 동작 을 한 번 터치 합 니 다.이렇게 하면 일반적으로 어떠한 성능 향상 도 가 져 오지 않 는 다.왜냐하면 그것 을 호출 할 때,아마도 이 시간 은 GC 의 좋 은 시기 가 아 닐 것 이다.
물론 예외 도 있다.프로그램 에 대한 벤 치마 킹 이 필요 할 때 나 메모리 에 대한 dumping 이 필요 할 때 명시 적 GC 가 필요 할 수도 있 습 니 다.
또한,-XX:+UseG1GC 명시 적 트리거 GC 를 금지 합 니 다.
총결산
사용 가능 한 CPU 가 하나 밖 에 없 을 때 직렬 회수 기 를 사용 하 는 것 이 좋 습 니 다.다른 GC 들 은 여러 스 레 드 를 시작 하기 때문이다
서로 다른 JVM 버 전과 OS 버 전 을 사용 할 때 기본 GC 는 직렬 회수 기와 스루풋 회수 기 이 며 CMS 나 G1 을 사용 하려 면 JVM Flags 를 사용 해 야 합 니 다
CMS 와 G1 은 백 스테이지 스 레 드 를 실행 하기 위해 추가 적 인 CPU 자원 이 필요 합 니 다.이러한 백 스테이지 스 레 드 는 Old Generation 을 주기 적 으로 회수 하여 Full GC 를 최소 화 합 니 다

좋은 웹페이지 즐겨찾기