젊은 세대와 구세대 쓰레기 수거

복사 알고리즘


더 많은 블로그 콘텐츠를 보려면 용과만 먹고 싶어 방문하십시오 . 자세한 내용을 보려면 클릭하세요.


  • 개요

복사 알고리즘은 메모리를 두 개의 간격으로 나눕니다 . 어느 시점에서든 동적으로 할당된 모든 객체는 간격 중 하나(활성 간격이라고 함)에만 할당할 수 있고 다른 간격(여유 간격이라고 함)은 비어 있습니다.
유효 메모리 공간이 소진되면 JVM은 프로그램 실행을 일시 중단하고 복사 알고리즘 GC 스레드를 시작합니다. 다음으로 GC 스레드 활성 영역의 모든 살아남은 개체를 빈 영역으로 복사 하고 메모리 주소에 따라 엄격하게 배열합니다.동시에 GC 스레드는 살아남은 개체의 메모리 참조 주소를 포인트로 업데이트합니다. 새로운 메모리 주소로.

  • 복제 알고리즘의 장점
  1. 공간의 연속성을 보장하기 위해 "파편화" 문제가 없습니다.
  2. 표시가 없고 프로세스가 명확하며 구현하기 쉽고 효율적으로 실행
  • 복제 알고리즘의 최적화

메모리는 1개의 Eden 영역과 2개의 Survivor 영역 으로 나누어져 있는데, Eden 영역은 메모리 공간의 80%를 차지하고 각 Survivor 영역은 메모리 공간의 10%를 차지합니다. 영역에는 100MB의 메모리가 있습니다.
Survivor 영역에서 하나는 From, 하나는 To라고 하며 Eden 및 From 블록에 오브젝트가 존재합니다. GC를 수행하면 Eden의 모든 생존 객체는 To 블록으로 이동되고, From의 경우에는 age 값에 따라 생존 객체가 결정되어 일정 값에 도달하면 old generation으로 이동되고, 값에 도달하지 않은 개체는 To 블록에 복사됩니다. , GC 후 Eden 및 From이 비워집니다. 그 후 From과 To가 역할을 교환하여 새로운 From은 원래 To 블록이고 새로운 To 블록은 원래 From 블록이며 새로운 To 블록에 있는 개체의 나이는 1씩 증가합니다.
참고: 연령 임계값은 -XX:MaxTenuringThreshold로 설정할 수 있습니다.

마이너GC 프로세스

  • 트리거 타이밍:

에덴 지역이 가득 차면 발동되지만 서바이버 지역은 GC 발동이 되지 않습니다.

  • 설명하다

코드가 실행되는 동안 다양한 객체가 지속적으로 생성되며 이러한 객체는 New Generation의 Eden 영역과 Survivor1 영역에 우선적으로 배치됩니다 .
여기에 이미지 설명 삽입

신세대의 Eden 영역과 Survivor1 영역이 모두 거의 차면 이때 Minor GC가 발생하여 살아남은 객체를 Survivor2 영역으로 옮긴다. 이때 에덴 지역의 모든 생존 오브젝트는 빈 생존자 지역으로 한번에 이동됩니다. 그러면 에덴 지역이 정리됩니다.여기에 이미지 설명 삽입

그런 다음 다시 Eden 영역에 새 개체를 할당합니다.Eden 영역과 Survivor 영역에 개체가 있습니다.Survivor 영역에는 마지막 Minor GC에서 살아남은 개체가 포함됩니다. 다음에 다시 Eden 영역이 가득 차면 Minor GC가 다시 발생하고, 마지막 Minor GC 이후에 살아남은 오브젝트가 놓인 Eden 영역과 Survivor 영역의 살아남은 오브젝트는 다른 Survivor 영역으로 이전됩니다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

객체가 이전 세대에 들어갈 때

대상 연령에 따라

새로운 세대에서 객체가 MinorGC를 벗어나 Survivor 영역으로 옮겨질 때마다 나이가 1년씩 늘어나며, 기본적으로 개체가 15살이 되면 15살을 피해 다음 GC에서 옮겨진다 . 구세대에게 . 자녀가 노년에 진입하는 구체적인 연령은 JVM 파라미터 "-XX:MaxTenuringThreshold"를 통해 설정할 수 있으며 기본값은 15세이다.
여기에 이미지 설명 삽입

동적 개체 연령 판단

객체가 15개의 GC가 통과할 때까지 기다리지 않고 오래된 나이에 들어갈 수 있도록 허용하는 또 다른 규칙이 있습니다.
현재 생존자 영역에서 객체 배치의 총 크기가 이 생존자 영역의 메모리 크기의 50%를 초과하면 이 객체 배치의 수명보다 크거나 같은 수명을 가진 객체는 이전 영역에 직접 들어갈 수 있습니다. 나이.
여기에 이미지 설명 삽입

이 그림에서 Survivor2 영역에 3개의 객체가 있다고 가정하면 이 객체들의 나이는 같고 모두 3년이며 두 객체를 합친 객체는 100MB 메모리의 절반 이상인 50MB를 초과합니다. Survivor2 영역의 크기 이 때 Survivor2 영역에는 3년 이상 된 개체가 모두 Old Generation에 들어갑니다. 이것은 소위 동적 연령 판단 규칙이며, 이 규칙은 또한 새로운 세대의 일부 개체가 노년에 진입하도록 허용합니다.
또한 여기에 명확히 할 개념이 있습니다. 즉, 이 규칙의 실제 논리는 다음과 같습니다: 1세+2세+n세의 여러 연령 개체의 합이 생존자 영역의 50%를 초과합니다. 구세대 .

큰 객체는 Old Generation으로 바로 이동합니다.

" -XX:PretenureSizeThreshold " 인 JVM 매개변수가 있으며 , 값을 바이트 수(예: 1MB인 "1048576"바이트)로 설정할 수 있습니다. 초대형 배열이나 다른 것과 같이 이 크기보다 큰 객체를 생성하려는 경우 이 큰 객체를 이때 Old Generation에 직접 넣을 수 있음을 의미합니다. 새로운 세대를 거치지 않을 것입니다. 그 이유는 New Generation에서 이러한 Large Object의 발생을 피한 후 반복적으로 GC를 피한 후 Old Generation에 진입하기 전에 두 Survivor 영역 사이에서 여러 번 복사를 반복하기 위함이다.

마이너 GC 후 객체가 너무 많습니다.

Minor GC 이후 잔존 객체가 너무 많은 것으로 확인되어 다른 Survivor 영역에 넣을 방법이 없으며, 이때 이러한 객체를 Old Generation으로 직접 전송해야 한다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

구세대 공간 할당 보장 규칙

  • 질문 리드

만약 New Generation에서 많은 수의 객체가 살아남는다면 Survivor 영역이 이를 수용하지 못하고 Old Generation으로 옮겨야 하는 것이 사실인데 이러한 객체를 저장할 공간이 Old Generation에 충분하지 않다면?

  • 해결하다

우선, Minor GC를 실행하기 전에 JVM은 먼저 이전 세대에서 사용 가능한 메모리 공간이 새로운 세대의 모든 객체의 총 크기보다 큰지 여부를 확인합니다. 가장 극단적인 상황을 방지하기 위해 모든 개체는 신세대의 마이너 GC에서 살아남을 수 있으며 신세대의 모든 개체는 구세대로 진입합니다.
Old Generation의 메모리 크기가 New Generation의 모든 객체보다 크다고 판단되면 Minor GC 이후 모든 객체가 살아남더라도 Survivor는 새로운 Generation에서 Minor GC를 시작할 수 있습니다. 영역이 더 이상 맞지 않고 이전 세대로 이전될 수 있습니다.
Minor GC를 수행하기 전에 Old Generation의 사용 가능한 메모리가 New Generation의 모든 객체 크기보다 작다면 이때 Minor 이후 New Generation의 모든 객체가 살아남을 가능성이 있습니다. GC, 그런 다음 모두 구세대로 이전해야 하지만 구세대에는 나이 공간이 충분하지 않습니다. 따라서 Minor GC 이전이면 "-XX:-HandlePromotionFailure" 파라미터가 설정되어 있는지 확인하고 이 파라미터가 있으면 계속해서 다음 판단을 시도한다.

  • Old Generation의 메모리 크기가 각 Minor GC 후 Old Generation에 진입하는 객체의 평균 크기보다 큰지 확인합니다.

예를 들어 각 마이너 GC 후에 평균 약 10MB의 개체가 이전 세대에 들어가므로 현재 이전 세대에서 사용 가능한 메모리는 10MB보다 큽니다. 이는 Minor GC 이후 약 10MB 정도의 객체가 Old Generation에 들어갈 가능성이 매우 높다는 것을 의미하며 이때 Old Generation의 공간은 충분하여 재활용이 가능하다.

  • 위 단계의 판단이 실패하거나 "-XX:-HandlePromotionFailure" 매개변수가 설정되지 않은 경우 "Full GC"가 바로 이때 트리거되어 이전 세대에서 가비지 수집을 수행합니다. 약간의 메모리 공간을 확보한 다음 Minor GC를 수행합니다.
  • 요약하다

Minor GC가 발생하기 전에 가상 머신은 이전 세대의 최대 사용 가능한 연속 공간이 새로운 세대의 모든 개체의 총 공간보다 큰지 확인합니다.

  1. 보다 크면 이 Minor GC가 안전합니다.
  2. 미만인 경우 가상 머신은 -XX:-HandlePromotionFailure 설정 값이 보장 실패를 허용하는지 여부를 확인합니다.
    1. HandlePromotionFailure=true인 경우 이전 세대에서 사용 가능한 최대 연속 공간이 이전 세대로 승격된 개체의 평균 크기보다 큰지 계속 확인합니다.
      1. 더 큰 경우 Minor GC를 시도하지만 이 Minor GC는 여전히 위험합니다. old generation, "Handle Promotion Failure" 발생 이 경우 "Full GC"가 이때 트리거됨
      2. 그 미만이면 대신 Full GC를 수행하십시오.
    2. HandlePromotionFailure=false인 경우 대신 전체 GC를 수행합니다.
  3. HandlePromotionFailure 매개변수는 JDK7 이후 유효하지 않습니다.Old Generation의 연속 공간이 New Generation 개체의 총 크기보다 크거나 Old Generation으로 승격된 개체의 평균 크기보다 크면 MonitorGC가 수행됩니다. FullGC

구세대 가비지 수집 알고리즘

마크업 조합 알고리즘

복사 수집 알고리즘은 개체 생존율이 높을 때 더 많은 복사 작업이 필요하고 효율성이 떨어집니다. 더 중요한 것은 메모리 공간의 50%를 낭비하지 않으려면 할당 보장을 위한 추가 공간을 제공해야 합니다. 구세대 객체의 생존율이 상대적으로 높고 할당 보장을 위한 다른 메모리를 찾을 수 없기 때문에 구세대는 일반적으로 이 수집 알고리즘을 직접 사용할 수 없습니다.
이전 세대의 특성에 따라 누군가 "mark-clear"를 개선하여 "mark-sort" 알고리즘을 제안했습니다. "mark-sort" 알고리즘의 마킹 과정은 "mark-clear" 알고리즘과 동일하나, 이후 단계는 재활용품을 직접 정리하는 것이 아니라 살아남은 모든 개체를 한쪽 끝으로 이동시킨 다음 직접 끝 경계 외부의 객체 정리 메모리 .
여기에 이미지 설명 삽입

트리거 타이밍

  1. System.gc를 호출할 때 시스템에서 Full GC를 실행하도록 제안하지만 반드시 그런 것은 아닙니다.
  2. Old Generation의 공간 부족
  3. 공간 할당 보장 실패
  4. JDK 1.7 및 이전 영구 생성(메서드 영역) 공간이 부족합니다.
  5. Minor GC 후 Old Generation의 평균 크기는 Old Generation의 사용 가능한 메모리보다 큽니다.
  6. CMS GC가 부동 쓰레기를 처리할 때 차세대 공간이 부족하면 공간 할당 보장 메커니즘이 채택되고 구세대 공간이 부족하면 Full GC가 트리거됩니다.

Old GC 실행 시 Young GC 가져오기

  • OldGC 트리거 조건
  1. Young GC가 발생하기 전에 확인하십시오. 이 Young GC 이후 Old Generation으로 승격 현재 Old Generation의 가용 메모리 공간을 초과할 수 있으므로 Old GC를 발생시켜 Old Generation을 위한 공간을 확보한 후 Young GC를 수행한다.
  2. Young GC 실행 후 Old Generation에 객체 배치를 넣어야 하는데, 이때 Old Generation은 이러한 객체를 저장할 메모리 공간이 부족하므로 즉시 Old GC를 트리거해야 한다( Old Generation의 남은 공간은 Old Generation에 들어가는 이전 Young Generation의 평균 크기보다 크지만, 이 재활용 후 Old Age에 들어가는 개체는 이전 평균 크기보다 훨씬 큽니다.)
  3. Old generation의 메모리 사용률이 92%를 초과하면 Old GC를 직접 트리거해야 하며, 이 비율은 파라미터를 통해 조정할 수 있다.

쉽게 말해 Old Generation은 공간이 부족하고 더 이상 객체를 배치할 수 없기 때문에 Old GC를 수행하여 Old Generation에서 가비지를 수집해야 한다.

  • 설명하다
  1. 조건 1에 의해 Old GC가 발생한 경우 Old Generation 공간이 부족하여 Young GC를 수행할 수 없음을 의미하며, Old GC를 먼저 수행한 후 Young GC를 수행하여 Yonug GC보다 먼저 Old GC가 발생하도록 해야 한다.
  2. 조건 2에 의한 경우 Young GC 이후 공간이 부족하여 Old GC가 발생한다.
  3. 실제로 많은 JVM 구현 메커니즘에서 위의 조건이 충족되면 실제로 Full GC가 트리거되며 이 Full GC에는 Young GC, Old GC 및 영구 생성 GC가 포함됩니다.

추천

출처blog.csdn.net/u010859650/article/details/127975798