이 튜토리얼은 기본 Java Garbage Collection과 작동 방식을 이해하는 것입니다. 이것은 쓰레기 수집 자습서 시리즈의 두 번째 부분입니다. 첫 번째 부분을 읽었 으면 좋겠습니다. " Java Garbage Collection 메커니즘에 대한 간단한 소개 ".
Java Garbage Collection은 프로그램에서 사용하는 런타임 메모리를 관리하는 데 사용되는 자동화 된 프로세스입니다. 이 자동화 프로세스를 통해 JVM은 프로그래머의 오버 헤드를 제거하여 프로그램에 메모리 리소스를 할당하고 자유롭게 메모리 리소스를 할당합니다.
Java Garbage Collection을 시작하십시오
자동 프로세스로서 프로그래머는 코드에 표시된 쓰레기 수집 프로세스를 시작할 필요가 없습니다. System.gc () 및 runtime.gc ()는 JVM에 쓰레기 수집을 시작하도록 요청하는 데 사용됩니다.
이 요청 메커니즘은 프로그래머에게 GC 프로세스를 시작할 수있는 기회를 제공하지만 시작은 JVM의 책임입니다. JVM 은이 요청을 거부 할 수 있으므로 이러한 모든 통화가 쓰레기 수집을 수행한다는 보장은 없습니다. 시작 타이밍 선택은 JVM에 의해 결정되며 힙 메모리에서 Eden 영역을 사용할 수 있는지 여부에 따라 다릅니다. JVM은 이러한 선택을 Java 사양의 구현에 남겨두고 다른 구현에서 사용되는 특정 알고리즘은 다릅니다.
말할 것도없이, 우리는 쓰레기 수거 과정을 시행 할 수 없다는 것을 알고 있습니다. 방금 System.gc ()가 의미가있는 장면을 찾았습니다. 이 기사를 통해 System.gc () 호출에 적합한 극단적 인 상황에 대해 알아 보겠습니다.
자바 쓰레기 수거 과정
쓰레기 수집은 쓸모없는 메모리 공간을 되찾아 향후 인스턴스에서 사용할 수 있도록하는 과정입니다.
에덴 지역 : 인스턴스가 만들어지면 먼저 젊은 세대의 힙 메모리의 에덴 지역에 저장됩니다.
참고 :이 단어를 이해할 수 없다면 메모리 모델, JVM 아키텍처 및이 용어에 대한 자세한 소개를 제공하는이 용어를 제공하는이 용어를 읽는 것이 좋습니다.
생존자 구역 (S0 및 S1) : 젊은 세대 GC (MinorGC) 사이클의 일환으로 생존 객체 (여전히 참조 된)는 Eden Zone에서 Survivor Zone의 S0으로 이동됩니다. 마찬가지로, 쓰레기 수집기는 S0을 스캔하고 생존 인스턴스를 S1로 옮깁니다.
(번역가 노트 : Eden과 S0의 살아남은 사람들이 S1로 이동하지 않습니까? 왜 S0으로, S0에서 S1로 이동합니까?)
사망 사례 (더 이상 참조되지 않음)는 쓰레기 수집으로 표시됩니다. 쓰레기 수집기 (일반적으로 사용되는 쓰레기 수집기 4 개가 다음 자습서에 설명 될 4 개의 쓰레기 수집기가 있습니다)에 따라 태그가 지정된 인스턴스가 메모리에서 지속적으로 제거되거나 재활용 프로세스가 별도의 프로세스에서 완료됩니다.
오래된 세대 : 구형 세대는 힙 메모리의 두 번째 논리 영역입니다. 쓰레기 수집기가 마이너 GC주기를 수행 할 때, S1Survivor 영역의 생존 인스턴스는 노년까지 홍보되는 반면, 비호사되지 않은 물체는 재활용 된 것으로 표시됩니다.
Old GC (Majorgc) : Java Garbage Collection 프로세스와 비교하여 Old GC는 인스턴스 수명주기의 마지막 단계입니다. MajorGC는 노인의 쓰레기 재활용 과정을 스캔합니다. 인스턴스가 더 이상 참조되지 않으면 재활용으로 표시됩니다. 그렇지 않으면 노년에 계속 머무를 것입니다.
메모리 샤드 : 인스턴스가 힙 메모리에서 삭제되면 위치가 비어 있고 향후 인스턴스를 할당하는 데 사용할 수 있습니다. 이 자유 공간은 전체 메모리 영역을 조각화합니다. 인스턴스를 빠르게 할당하려면 탈퇴가 필요합니다. 쓰레기 수집기의 다른 선택에 기초하여, 재활용 메모리 영역은 별도의 GC 프로세스에서 지속적으로 분류되거나 완료됩니다.
쓰레기 수집의 인스턴스 끝
인스턴스를 풀고 메모리 공간을 되 찾기 전에 Java Garbage Collector는 인스턴스의 각 Finalize () 메소드를 호출하여 인스턴스가 보유한 리소스를 확보 할 수있는 기회를 갖도록합니다. 메모리 공간을 되 찾기 전에 Finalize ()가 호출되도록 보장되지만 지정된 순서와 시간은 없습니다. 여러 인스턴스 간 순서는 예측할 수 없으며 병렬로 발생할 수도 있습니다. 프로그램은 finalize () 메소드를 사용하여 인스턴스와 재활용 리소스 간의 순서를 사전 조정해서는 안됩니다.
최종 프로세스에 포착되지 않은 예외는 자동으로 무시되고 인스턴스의 마무리 프로세스가 취소됩니다.
JVM 사양은 약한 참조에 대한 쓰레기 수집 메커니즘에 대해서는 논의하지 않으며 명확한 요구 사항이 없습니다. 특정 구현은 구현 당사자에 의해 결정됩니다.
쓰레기 수집은 데몬 스레드에 의해 수행됩니다.
물체는 언제 쓰레기 수집 조건을 충족합니까?
모든 인스턴스에는 활성 스레드 액세스가 없습니다.
다른 인스턴스에서 액세스하지 않는 원형 참조 인스턴스.
Java에는 다른 참조 유형이 있습니다. 인스턴스가 가비지 수집 조건을 충족하는지 여부를 결정하는 것은 모두 참조 유형에 따라 다릅니다.
| 참조 유형 | 쓰레기 수집 |
|---|---|
| 강한 참조 | 쓰레기 수집을 준수하지 않습니다 |
| 소프트 참조 | 쓰레기 수집이 수행 될 수 있지만 최후의 수단이 될 것입니다. |
| 약한 참조 | 쓰레기 수집을 준수하십시오 |
| 팬텀 참조 | 쓰레기 수집을 준수하십시오 |
컴파일 프로세스 중 최적화 기술로서 Java 컴파일러는 인스턴스에 NULL 값을 할당하도록 선택하여 인스턴스를 재활용 가능로 표시 할 수 있습니다.
클래스 동물 {public static void main (String [] args) {동물 lion = new Animal (); System.out.println ( "메인이 완료되었습니다."); } protected void finalize () {system.out.println ( "평화로운!"); }}위의 클래스에서 라이온 객체는 선을 인스턴스화 한 후에 사용되지 않았습니다. 따라서 최적화 측정으로 Java 컴파일러는 행을 인스턴스화 한 후 lion = null을 직접 할당 할 수 있습니다. 따라서 최종 기능은 'Restinpeace!'를 인쇄 할 수 있습니다. SOP 출력 전에도. 우리는 JVM이 구현되는 방식과 런타임에 사용되는 메모리에 달려 있기 때문에 이것이 일어날 것이라는 것을 증명할 수 없습니다. 그러나 우리는 하나 더 배울 수 있습니다. 컴파일러가 인스턴스가 향후 인스턴스를 참조하지 않을 것을 알면 인스턴스 공간을 조기에 선택하고 자유롭게 할 수 있습니다.
물체가 쓰레기 수집을 준수하는 시점에 대한 더 나은 예가 있습니다. 인스턴스의 모든 속성은 레지스터에 저장된 다음 액세스하고 읽습니다. 예외 없이이 값은 인스턴스로 다시 기록됩니다. 이러한 값은 향후 사용될 수 있지만이 인스턴스는 여전히 쓰레기 수집을 준수하는 것으로 표시 될 수 있습니다. 이것은 매우 고전적인 예입니다. 그렇지 않습니까?
이것은 NULL에 할당 할 때 쓰레기 수집을 준수하는 매우 간단한 예입니다. 물론 복잡한 상황은 위의 점과 같을 수 있습니다. 이것은 JVM 구현자가 선택한 것입니다. 목적은 가능한 한 가장 작은 메모리 발자국을 남겨두고 응답 속도를 높이며 처리량을 향상시키는 것입니다. 이를 달성하기 위해 JVM 구현자는 쓰레기 수집 프로세스 중에 메모리 공간을 회수하기 위해 더 나은 솔루션 또는 알고리즘을 선택할 수 있습니다.
Finalize () 메소드가 호출되면 JVM은 스레드의 모든 동기화 잠금을 릴리스합니다.
GCSCOPE 샘플 프로그램
클래스 gcscope {gcscope t; static int i = 1; public static void main (string args []) {gcscope t1 = new gcscope (); gcscope t2 = new gcscope (); gcscope t3 = new gcscope (// no 객체는 gct1.t에 적합하지 않습니다. T3; // gct3.t = t1에 적합하지 않은 객체는 없습니다. // gct1 = null; // 객체가 GC에 적합하지 않습니다 (t3.t는 여전히 t1에 대한 참조) t2 = null; // 객체가 GC에 대한 자격이 없음 (t3. t3 = 널에 대한 참조)가 없습니다. 참조 ./ // 객체의 변수만이 외부 // 참조를 사용하여 물체의 섬을 형성하는 둥근 방식으로 서로를 참조하고 있습니다. {gcscope t1 = new gcscope (); gcscope t2 = new gcscope (); gcscope t3 = new gcscope (); // 객체가 gct1.t = t2를 준수하지 않습니다. gc (t3.t는 여전히 t1에 대한 참조를 가지고있다) t2 = null; // 객체는 GC를 준수하지 않습니다 (t3.tt는 여전히 t2에 대한 참조가 있습니다) t3 = null; // 세 객체는 모두 GC를 준수합니다 (아무것도 참조가 없습니다. {System.out.println ( "객체에서 수집 한 쓰레기"+i); i ++;}GC OutofMemoryError 샘플 프로그램
GC는 메모리 오버 플로우 문제의 보안을 보장하지 않으며, 부주의 한 코드로 작성되면 MemoryError가 발생합니다.
import java.util.linkedList; import java.util.list; public class gc {public static void main (string [] main) {list l = new LinkedList (); // 목록에 문자열을 추가 할 무한 루프를 입력합니다.산출:
스레드의 예외 "main"java.lang.outofmemoryerRor : java.util.linkedlist.linklast (linkedlist.java:142)의 java 힙 스페이스 : java.util.linkedlist.add (linkedlist.java:338) at com.javapapers.java.gcscope.main (gcscope.java:12)
요약
위의 것은 Java Garbage Collection의 구현 프로세스를 간략하게 논의하는 것에 대한이 기사의 전체 내용입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!