기술나눔

[JVM 기초] 자바 가비지 콜렉터 소개

2024-07-11

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

가비지 수집기(가비지 수집 알고리즘 구현)

가비지 수집기는 가비지 수집 알고리즘의 특정 구현입니다. . 가비지 컬렉터는 Young Generation과 Old Generation으로 나누어져 있기 때문에 G1(New Generation과 Old Generation을 모두 제어할 수 있음) 외에도신세대 및 구세대 가비지 수집기는 핫스팟 요구 사항에 따라 쌍으로 사용해야 합니다.(JDK 버전에 따라 해당 조합을 선택해야 합니다)

구체적인 조합 관계는 다음과 같습니다.

여기에 이미지 설명을 삽입하세요.

JVM 기본 소스 코드에서 일부 특수한 경우 CMS 리사이클러는 Serial Old 리사이클러를 호출합니다.

Arthas는 사용된 가비지 수집기를 봅니다.

어떤 가비지 컬렉터가 사용되었는지 직접 확인할 수는 없고, 알고리즘을 기반으로 유추만 할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

젊은 세대 직렬 가비지 수집기

시리얼은젊은 세대의 단일 스레드 직렬 컬렉션가비지 수집기입니다.

여기에 이미지 설명을 삽입하세요.

재활용 연령 및 알고리즘

  • 젊은 세대
  • 복제 알고리즘

이점

단일 CPU 프로세서에서 뛰어난 처리량

결점

다중 CPU에서의 처리량은 다른 가비지 수집기(단일 스레드, 하나의 CPU만 사용)만큼 좋지 않습니다. 힙이 너무 크면 사용자 스레드가 오랜 시간 동안 대기하게 됩니다.

적용 가능한 장면

Java로 작성된 클라이언트 프로그램 또는 하드웨어 구성이 제한된 시나리오(CPU 코어가 많지 않음)

사용하는 방법

-XX: UseSerialGC: 신세대와 구세대 모두 시리얼 콜렉터를 사용합니다.

이전 세대-SerialOld 가비지 수집기

SerialOld는 다음을 사용하는 직렬 가비지 수집기의 이전 세대 버전입니다.단일 스레드 직렬 컬렉션

여기에 이미지 설명을 삽입하세요.

재활용 연령 및 알고리즘

  • 노년
  • 마크 콜레이션 알고리즘

이점

단일 CPU 프로세서에서 뛰어난 처리량

결점

다중 CPU에서의 처리량은 다른 가비지 수집기만큼 좋지 않습니다. 힙이 너무 크면 사용자 스레드가 오랫동안 대기하게 됩니다.

적용 가능한 장면

직렬 가비지 수집기와 함께 사용되거나 CMS 특별한 경우에 사용됩니다.

사용하는 방법

-XX: UseSerialGC: 신세대와 구세대 모두 시리얼 콜렉터를 사용합니다.

젊은 세대-ParNew 가비지 컬렉터

ParNew 가비지 수집기는 기본적으로다중 CPU에서 직렬 최적화, 가비지 수집을 위해 멀티스레딩 사용

여기에 이미지 설명을 삽입하세요.

재활용 연령 및 알고리즘:

  • 젊은 세대
  • 복제 알고리즘

이점

  • 다중 CPU 프로세서에서 더 짧은 일시 중지 시간

결점

  • 처리량과 정지 시간이 G1만큼 좋지 않아 JDK9 이후에는 권장하지 않습니다.

적용 가능한 장면

  • JDK8 및 이전 버전에서는 CMS 이전 세대 가비지 수집기와 함께 사용됩니다.

사용하는 방법

  • -XX: UseParNewGC: 신세대는 ParNew 컬렉터를 사용하고, 구세대는 시리얼 컬렉터를 사용합니다.

여기에 이미지 설명을 삽입하세요.

구세대-CMS(Concurrent Mark Sweep) 가비지 수집기

CMS 가비지 수집기는 시스템의 일시 중지 시간(STW를 최소화하고 사용자 경험을 최적화하기 위해)에 중점을 둡니다.사용자 스레드와 가비지 수집 스레드가 특정 단계에서 동시에 실행되도록 허용, 사용자 스레드의 대기 시간을 줄입니다.

재활용 연령 및 알고리즘

  • 노년
  • 마크 앤 스윕 알고리즘

이점

  • 가비지 수집으로 인한 시스템 일시 중지 시간이 짧아지고 사용자 경험이 향상됩니다.

결점

1. 메모리 조각화 문제

2. 성능 저하 문제(일부 특정 경우 SerialOld와 같은 단일 스레드 수집기로 퇴화됨)

3. 떠다니는 쓰레기 문제 (일부 쓰레기는 재활용 과정에서 재활용이 불가능함)

적용 가능한 장면

사용자가 주문 인터페이스, 제품 인터페이스 등과 같이 대량의 데이터와 높은 빈도를 요청하는 대규모 인터넷 시스템의 시나리오

사용

XX: UseConcMarkSweepGC, Young Generation과 Old Generation의 Collector를 각각 설정할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

CMS 실행 단계

  1. 초기 마킹, 매우 짧은 시간에 마킹GC Roots가 직접 관련될 수 있는 개체
  2. 동시 마킹, 모든 개체 표시 , 사용자 스레드를 일시 중지할 필요가 없습니다. (동시 마킹은 사용자 스레드와 함께 수행되지만, 동시 마킹에 의해 차지하는 자원이 많으면 사용자 스레드에도 영향을 미칩니다)
  3. Remarking(동시성), 동시 마킹 단계에서 일부 객체가 변경되기 때문에 라벨이 잘못 지정될 수 있습니다(사용된 객체는 원래 살아 있었지만 마킹 후 사용자 스레드가 실행 불가능하게 만들어 라벨이 잘못 지정됨), 라벨링 누락(왜냐하면 이는 동시적이며 일부 개체는 사용자 스레드에 의해 방금 생성되었을 수 있으며 이로 인해 태그가 누락될 수 있습니다.) 및 기타 상황이 발생하므로 다시 표시해야 합니다.
  4. 동시 정리, 죽은 개체 정리, 사용자 스레드를 일시 중지할 필요가 없습니다.

참고: STW는 초기 표시 및 재표시 단계에서만 나타납니다.

여기에 이미지 설명을 삽입하세요.

결점:

1. CMS는 가비지 수집이 완료된 후 객체 할당에 영향을 주지 않기 위해 많은 수의 메모리 조각이 나타납니다.CMS는 Full GC 중에 조각 모음을 수행합니다. . 이로 인해 사용자 스레드가 일시 중지되고,-XX:CMSFullGCsBeforeCompaction=N 매개변수(기본값 0)를 사용하여 정렬하기 전에 전체 GC를 N번 조정할 수 있습니다.

2. 동시 정리 프로세스 중에 생성된 "떠다니는 쓰레기"를 처리할 수 없으며 완전한 가비지 수집을 달성할 수 없습니다(이 정리 프로세스 중에 사용자 스레드가 일부 개체를 동시에 생성했지만 곧 다시 사용되지 않았습니다. 이러한 개체는 아닙니다. 이번 청소에서 재활용되고 다음 청소 때까지 기다려야 하므로 부유쓰레기라고 합니다.)

3. Old 세대에 객체를 할당할 메모리가 부족하면 CMS는 Old 세대를 재활용하는 Serial Old 단일 스레드로 퇴보합니다.

동시 스레드 수:

CMS에서 동시 단계를 실행할 때 스레드 수를 전달할 수 있습니다.-XX:ConcGCThreads매개변수 설정은 시스템에 의해 계산되며 계산 공식은 다음과 같습니다.(-XX:ParallelGCThreads定义的线程数 3) / 4, ParallelGCThreads는 STW 일시 중지 후 병렬 스레드 수입니다.

ParallelGCThreads는 프로세서 코어 수에 따라 결정됩니다.

1. CPU 코어 수가 8개 미만인 경우 ParallelGCThreads = CPU 코어 수

2. 그렇지 않은 경우 ParallelGCThreads = 8(CPU 코어 수 – 8)*5/8

내 컴퓨터에는 12개의 논리 프로세서가 있으므로 ParallelGCThreads = 8 (12 - 8) * 5/8 = 10, ConcGCThreads = (-XX: ParallelGCThreads 3에서 정의한 스레드 수) / 4 = (10 3) / 4 = 삼

여기에 이미지 설명을 삽입하세요.

마지막으로 다음 사진을 얻을 수 있습니다.

여기에 이미지 설명을 삽입하세요.

동시 표시 및 동시 청소 단계는 세 개의 스레드를 사용하여 병렬로 처리됩니다. 재마킹 단계는 10개의 스레드를 사용하여 처리됩니다. CPU 코어 수가 제한되어 있으므로 동시 단계는 사용자 스레드 실행 성능에 영향을 미칩니다.

여기에 이미지 설명을 삽입하세요.

젊은 세대 병렬 청소 가비지 수집기

병렬 청소는JDK8 기본 젊은 세대 가비지 수집기, 멀티스레딩병렬 수집시스템 처리량에 집중 .처리량을 늘리기 위해 PS는힙 메모리 크기 자동 조정(신세대, 구세대 메모리 크기, 승격 임계값 조정)

여기에 이미지 설명을 삽입하세요.

재활용 연령 및 알고리즘

  • 젊은 세대
  • 복제 알고리즘

이점

  • 처리량이 높으며 처리량을 제어하기 위한 매개변수의 수동 설정을 지원합니다. 처리량을 향상시키기 위해 가상 머신은 힙의 매개변수를 동적으로 조정합니다(사용자는 처리량만 설정하면 되며 메모리 크기와 같은 다른 매개변수는 설정할 필요가 없습니다).

결점

  • 단일 일시 중지 시간은 보장되지 않지만 STW 시간 설정을 지원합니다.

적용 가능한 장면

  • 백그라운드 작업에는 사용자 상호 작용이 필요하지 않으며 많은 수의 개체를 생성하는 경향이 있습니다.예: 빅데이터 처리, 대용량 파일 내보내기

공통 매개변수

병렬 청소를 사용하면 최대 일시 중지 시간과 처리량을 수동으로 설정할 수 있습니다. Oracle 관계자는 이 조합을 사용할 때 최대 힙 메모리를 설정하지 않을 것을 권장합니다. 가비지 수집기는 최대 일시 중지 시간과 처리량을 기준으로 메모리 크기를 자동으로 조정합니다.

  • 최대 일시 정지 시간,-XX:MaxGCPauseMillis=n 각 가비지 수집에 대해 일시 중지할 최대 시간(밀리초) 설정
  • 처리량,-XX:GCTimeRatio=n 처리량을 n으로 설정합니다(사용자 스레드 실행 시간 = n/(n 1)).
  • 메모리 크기를 자동으로 조정하고, -XX: UseAdaptiveSizePolicy이 설정을 사용하면 가비지 수집기가 처리량 및 최대 일시 중지 밀리초를 기준으로 메모리 크기를 자동으로 조정할 수 있습니다. 이 매개변수는 기본적으로 활성화되어 있습니다. Oracle에서는 PS 조합을 사용할 때 최대 힙 메모리를 설정하지 않고 가비지 수집기가 자동으로 조정하도록 할 것을 권장합니다.

참고: 최대 일시 중지 시간과 처리량에 대한 두 가지 지표가 충돌합니다. 가비지 수집기는 최대 일시 중지 시간을 충족하기 위해 최선을 다합니다(때로는 너무 작게 설정되어 충족될 수 없으며 설정된 최대 일시 중지 시간이 초과됨). , 처리량을 희생합니다.최대 일시 중지 시간과 처리량을 동시에 설정하려면 더 많은 테스트를 수행하여 더 잘 조정해야 합니다.

구세대-병렬 구세대 가비지 컬렉터

Parallel Old는 다중 스레드 동시 수집을 활용하는 Parallel Scavenge 수집기를 위해 설계된 이전 세대 버전입니다.

여기에 이미지 설명을 삽입하세요.

재활용 연령 및 알고리즘

  • 노년
  • 표시 및 정렬 알고리즘(실제로는 표시 및 스윕 정렬)

이점

  • 동시 수집은 멀티 코어 CPU에서 더 효율적입니다.

결점

  • 휴지시간이 길어집니다

적용 가능한 장면

  • 병렬 청소와 함께 사용됨

사용하는 방법

JDK8은 기본적으로 이 리사이클러를 사용하도록 매개변수를 설정합니다.

매개변수:-XX: UseParallelGC 또는-XX: UseParallelOldGCParallel Scavenge Parallel Old 조합을 사용할 수 있습니다.
여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

시험

-XX: PrintFlagsFinal: 프로그램 시작 시 모든 구성 항목의 최종 값을 인쇄할 수 있으며, 자동 조정 기능이 켜져 있는지 확인할 수 있습니다.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

여기에 이미지 설명을 삽입하세요.

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 垃圾回收器案例3
 */
//-XX: UseSerialGC -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc -XX: PrintFlagsFinal
//-XX: UseParNewGC  -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc
//-XX: UseConcMarkSweepGC
//-XX: UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc MaxGCPauseMillis
//-XX: PrintFlagsFinal  -XX:GCTimeRatio = 19  -XX:MaxGCPauseMillis=10 -XX: UseAdaptiveSizePolicy
public class GcDemo2 {

    public static void main(String[] args) throws IOException {
        int count = 0;
        List