JVM 시리즈 - 심층 JVM 가비지 콜렉션의 이해

머리말

자바 가상 머신에서 자바 객체가 JVM에로드, 수명주기는 일곱 단계로 나누어 져 있습니다 :

위와 같이, 객체의 수명주기의 7 단계가 있었다 : 생성 단계, 응용 프로그램 단계, 무대, 표시되지 아니 상, 수집 단계, 무대의 끝과 오브젝트의 메모리 공간 재 할당 단계까지.

  • 창조 단계

무대를 만들기로 나눌 수 있습니다 :

(1) 오브젝트 공간 할당, (2) 객체 구축 (4) 재귀 호출 슈퍼 클래스 생성자, (5) 생성자 서브 호출 고정 부재 초기화 서브 클래스로 (3) 수퍼 클래스를;

  • 응용 프로그램 단계

애플리케이션 초기화 초기 값을 부여하면, 애플리케이션 단계로 전환. 이 단계에서 기준 개체는 적어도 강한 소프트 또는 명시 적 언급이 약한 참조 인용 거짓 갖는

  • 보이지 않는 무대

응용 프로그램에서 개체를 찾을 수 없습니다와 같은 프로그램의 구현 같은 강한 참조가 개체의 범위를 벗어납니다. 그러나 목표는 아직 가능성이 특별한 GC의 뿌리에 의해 개최 될 이번은, 예를 들어, 객체는 네이티브 메소드 스택 또는 JNI 참조가에 그렇게 실행 스레드에 의해 인용이다;

  • 도달 할 수없는 단계

객체는 임의의 강한 참조 인용하고, 가비지 컬렉터는 도달 할 수없는 찾을 수 없습니다;

  • 수집 단계

쓰레기 수집이 목적에 도달 할 수 있음을 발견하고, 준비 가비지 컬렉터 메모리 오브젝트를 재 - 할당합니다. 개체가 무시하는 가비지 컬렉터 발견하면 finalize()방법, 가비지 컬렉터가 객체의 면제를 수집하고, 호출 finalize()방법. 객체가 오버라이드 (override)하지 않는 경우 finalize()방법, 가비지 컬렉터 기다리고 객체의 메모리 공간을 회수합니다.

  • 최종 단계

이 때, 개체가 실행될 수있다 finalize()(GC는 반드시 객체의 마무리를 위해 () 메소드가 수행 종료를 기다릴 것) 방법을, 또는 객체는 무시하지 않는 finalize()방법, 개체의 메모리 공간을 수집하는 가비지 컬렉터를 기다리는이 시간을.

  • 오브젝트 공간 재 할당 단계

객체가 복구 된 GC 메모리 공간 경우, 객체의 라이프 사이클이 완전히 끝났습니다.

위, 객체는 JVM의 라이프 사이클에로드됩니다. Java 가상 머신, 복구 객체는 객체가 다른 객체에 의해 참조되지 일단이 도달 GC, GC로 표시하고 회복을 기다릴 수 있다는 것을 의미 프로그래머에게 보이지 않는다. Java 가상 머신 복구 오브젝트가 참조되지 않을 때, 그것은 타겟 마크를 받아야하며, 개체가 재활용 공정 가비지 컬렉터이다.

쓰레기 마킹 알고리즘

자바 가상 머신에서 쓰레기 오브젝트 (객체가 스팸 메일로 알려져 있습니다 때 개체가 다른 개체에 의해 유지되지 않은 경우) 알고리즘을 라벨로 나눌 수 있습니다 계산 참조도달 가능성 분석 (문서 접근성도 일부 루트 검색 알고리즘이라고 분석).

참조 카운팅

책은 "자바 가상 머신의 깊은 이해"에서, 기준의 계산 방법이 제공 정의에 대한 참조는, 카운터의 기준 값이 1만큼 증가 할 때마다 위의 개체 카운터에 대한 레퍼런스를 추가하는 단계; 고장을 참조 할 때 카운터 값이 1만큼 감소 될 때 0 언제 카운터 객체는 더 이상 사용중인. 이 객체, 다음 코드 간의 상호 참조의 문제를 해결하기 위해 매우 어렵 기 때문에 현재 주류 상업 가상 머신은, 참조 계산 방법을 사용하지 않는 :

참조 카운팅 알고리즘을 증명 _1

참조 카운팅 알고리즘을 증명 _2

코드로서, 때 실행

TestReferenceCountingGC gc_1 = new TestReferenceCountingGC();
TestReferenceCountingGC gc_2 = new TestReferenceCountingGC();

gc_1.instance = gc_2;
gc_2.instance = gc_1;
复制代码

경우 인하여 new TestReferenceCountingGC()new TestReferenceCountingGC()계산 알고리즘을 참조하는 경우에있어서, 두 객체는 두번 참조, new TestReferenceCountingGC()new TestReferenceCountingGC()카운터 값 2를 참조한다. 실행될 때 gc_1 = null;, 및 gc_2 = null;하면 실패 1 인용있을 것, new TestReferenceCountingGC()new TestReferenceCountingGC()참조 1이 Java 가상 머신이 참조 카운팅 알고리즘 마크 쓰레기 목적, 두 객체의 메모리 공간을 사용 그렇다면있다 가비지 수집기 아니다 다음과 같이 GC 로그가 나타납니다, 복구 :

[GC (System.gc()) [PSYoungGen: 9339K->4872K(76288K)] 9339K->4880K(251392K), 0.0057164 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
复制代码

다음과 같이 실제로, 그러나, GC 로그가 발생했습니다 :

[GC (System.gc()) [PSYoungGen: 9339K->776K(76288K)] 9339K->784K(251392K), 0.0015327 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
复制代码

GC는 참조 카운팅 알고리즘을 사용하지 않는 알고리즘을 자바 가상 머신을 표시 현재 증거 쓰레기 위에 기록합니다.

도달 가능성 분석

도달 성 분석의 주요 개념은 다음 참조 체인 (체인 참조)에 의해 이송 경로 검색 호출이 노드 아래 검색 출발 지점으로 GC 뿌리라는 일련의 객체 통해서이다. 연결된 체인에 대한 참조없이 GC 뿌리 객체 (이 오브젝트의 GC 뿌리로부터 그래프 이론이, 도달 할 수없는) 경우,이 목적을 증명하는 시간을 사용하지 않는다.

자바에서, 당신은 GC 루트로 다음 (부분)을 가질 수 있습니다 :

  • 객체 참조 가상 머신 스택 (로컬 변수 테이블 스택 프레임);
  • 개체 속성은 정적 프로세스 영역을 참조;
  • 최종 키 영역에있어서 일정 개체 참조 변성;
  • JNI 네이티브 메소드는 참조 된 개체를 스택;

참조 정의 전에 JDK 1.2 다음 VM 스택 기준값의 로컬 변수 테이블은 다른 메모리의 시작 주소 인 저장되는 데이터의 유형을 나타내고, 이것은 기준 메모리 나타내는 불린다. 그러나이 인수는 참조되는 정의를 정의하는 데 사용하고이 두 가지 상태를 참조 할 수는 없습니다. 메모리가 충분하면 가비지 수집하는 동안 메모리 공간, 메모리 풋 프린트가 아주 꽉 여전히, 당신은 이러한 개체를 복구 할 수 있습니다, 메모리에 저장되어 객체의 같은 클래스를 설명 할 수 있어야합니다.

따라서, 참조 강한 (강한 참조), 소프트 참조 (소프트 참조), 약한 참조 (weak 참조), 가상 참조 (Phanton 참조) 제조 :

  • 유사 강한 참조 Object obj = new Object()긴 같은 객체를 복구하지 않습니다 가비지 컬렉터에 대한 강한 참조가있는만큼 이러한 종류의 참조;

  • 강한 참조의 상대적 약화 숫자를 인용 소프트 참조는, 당신은 객체가 어떤 가비지 수집을 면제 할 수 있으며, JVM 메모리가 부족 생각하는 경우에만, 소프트 참조가 가리키는 복구합니다. JVM은 OOM을 던지기 전에 소프트 참조 객체를 가리키는 정리되도록 할 것이다;

  • 약한 참조 가비지 컬렉션은 면제 객체 참조 약한 상태로 진행하는 경우에만 액세스를 제공 할 수 없다. 다음 가비지 콜렉션이 발생할 때까지 만 살아남을 수있는 객체에 대한 약한 참조와 연결되어 있습니다. 가비지 컬렉터 작업에 관계없이 현재의 메모리가 충분한 경우에만 손실 된 객체가 약한 참조와 연관된 회복;

  • 팬텀 참조는 귀신이나 유령이 참고 문헌으로, 당신은 객체를 통해 액세스 할 수 없습니다 알려져있다. 팬텀 참조 객체를 제공하는 것을 보장하기 위해 전용 인 finalize()메커니즘이 후, 오브젝트가 가비지 수집 될 때의 통지를 수신하도록 상기 시스템 특정 것들을 할.

가비지 수집 알고리즘

마크 - 스윕 알고리즘

마크 - 스윕 알고리즘은 두 단계로 나누어 져 있습니다 :

  • 표시 단계 : 마크 개체를 복구 할 수 있습니다;
  • 지우기 단계 : 표시 대상 메모리의 복구;

마크 - 가비지 컬렉션 알고리즘은 상술 한 후자를 기준으로하기 때문에 가장 기본적인 알고리즘은,이 알고리즘의 변형은, 표시 스위프 알고리즘 - 스위프 알고리즘의 구현 프로세스가은 다음과 같다 :

- 마크 스위프 알고리즘은 두 가지 주요 단점 갖는다 : 제 1 마크 및 청소 효율이 높지 않고, 둘째로 너무 목표 공간, 개별 메모리 단편화 다량의 단편화를 라벨링 한 후에, 상기 투명한 재활용을 도시 후속으로 이어질 수하는 트리거를 가비지 컬렉션 액션의 새로운 라운드를 유발, 더 큰 객체에 충분한 메모리가 할당되지 않습니다.

복제 알고리즘

마크 해결하기 위해서 - 메모리 단편화로 인한 스위프 알고리즘의 문제 때문에, 순방향 카피 알고리즘을 넣어. 메모리 공간은 알고리즘 복제 메모리 공간 클린 아웃의 다른 조각을 넣고, 그 중 하나와 두 개의 동일한 크기로 각각 분할된다 :

복제 알고리즘 복제 결핍의 낮은 효율의 문제, 당신은 메모리 공간의 50 %를 낭비하고 싶지 않아, 당신은 응답 메모리에 모든 객체에 의해 사용되는 여분의 공간 보장을 제공하기 위해 극단적 인 경우 100 % 생존이 필요합니다.

마크 - 정렬 알고리즘을

기존의 알고리즘은 일반적으로 이전의 시대에, 대부분의 개체의 생존율이 상대적으로 높기 때문에, 그것은 낮은 효율의 결과로, 복사 작업을 선택 과도한 복제 알고리즘의 원인이됩니다, 몇 년 동안 사용하지 않을 복사합니다. 쉽게 쓰레기 수집 활동의 새로운 라운드를 유발 선도, 너무 많은 메모리 조각화를 생산하기 때문에, 청소 알고리즘 - 마크를 사용하지 않는 동안. (- 압축 알고리즘 마크) 정렬 알고리즘 - 따라서 표시되고있다. 마크 - 알고리즘 및 마크 마무리 - 스윕 알고리즘이 다르기는 메모리의 개체는 태그 후, 살아남은 객체는 함께 컴팩트하게 분류되어 있습니다 그래서, 메모리의 한 쪽 끝으로 압축하고, 객체 경계 외부 라이브 객체 재활용.

세대 모음

서로 다른 다양한 알고리즘과 함께 세대 수집 알고리즘은 그래서 자바 힙 공간 분할을 이해하는 세대 수집 알고리즘 최초의 필요성을 학습하기 전에, 다른 쓰레기 공간을 처리합니다. 새로운 세대가 생존자 생존자 공간과 공간에서 에덴 공간으로 분할하는 동안 Java 힙은, 새로운 세대 (젊은 세대) 및 이전 년 (종신 세대)으로 구분된다. 자바 힙 내부에 있기 때문에, 대부분의 개체는 "저녁 오프쪽으로 탄생"하고 개체의 수명주기의 몇이 긴만큼 다른 개체 수명주기를 사용하는 가상 머신의 심지어 일부 개체 수명주기 및 수명주기 비교적 긴이며, 세대 콜렉션의 개념 다른 가비지 컬렉션 알고리즘.

자바 힙 공간의 구분에 따르면, 가비지 컬렉션에 대부분은 두 가지 방법으로 나눌 수 있습니다 :

  • 마이너 GC : 새로운 세대 가비지 콜렉션;
  • 전체 GC : 또한 주요 GC로 알려진이, 전체 GC는 일반적으로 적어도 하나의 마이너 GC, 수집의 낮은 주파수를 동반, 시간이 오래 걸립니다.

마이너 GC를 수행 할 때 생존자 공간 객체에서 살아남은도받는 생존자 공간에 복사하는 동안 에덴 공간을 복사하는 가상 머신은 모든 내부 생존자 공간에서에 생존자 공간을 생존을 위해 다음 다음 공간과 에덴 객체 때 클리어는 그 이름이 온 다음 마이너 GC를 기다리는 생존자 공간에서 생존자에 공간이되고,이 시간 생존자 공간에서 생존자에 대한 포인터를 가리키는 공간 객체. 물론, 모든 새로운 객체가 새로운 개체가 사용 가능한 공간 에덴 공간보다 메모리 공간을 점유 할 필요가 에덴의 공간에 할당되는 새로운 객체가 이전 시대에 직접 할당됩니다 훨씬 더 크다.

객체가 여전히 마이너 GC의 특정 번호를 통해 새로운 세대 후 살아 경우, VM 개체가 이전 시대로 승진했다 둘 것이다. 각 개체에 대한 가상 머신은 대상 연령 (나이) 카운터를 정의합니다. 아직 살아과 생존자 공간을 수용 할 수있는 마이너 GC 에덴을 통해 공간에서 새로운 객체가, 연령 카운터했을 때 다음, 1 마이너 GC를 통해 각 개체를 설정, 하나, 경우에 의해 증가하고있는 객체 카운터의 나이를 넣어 승진 나이의 임계 값에 도달하는 연령 카운터 개체가 개체가 이전 시대로 승격되며, 일반 가상 머신을 15로 설정되어 있습니다.

물론, 가상 머신은 반드시 객체의 홍보 프로 모션에 대 나이의 문턱에 도달 한 연령 카운터 값을 대상으로 할 필요가 없습니다. 모두 같은 나이 생존자 공간의 합은 공간 생존자의 큰 절반 크기보다 나이 더 큰 객체 또는 예전과 나이 나이 충족 추진 임계 값에 카운터의 값이 될 때까지 기다리지 않고 년 입력 할 수있는 주제의 나이에 동일합니다.

개요

또한 조금 과도한 길이를 느끼고, 메모리 할당 및 복구 전략도 여기에 기록 된 GC 로그 분석하지만,이 장 Miaole 미아오 공간으로 구성했다, 하, 하, 하 ... 그 .... 나는 그것을 쓰지 않는다 .

추천

출처juejin.im/post/5e81e0075188257382097586