아래에서 소개해드릴 내용은 GC 알고리즘 중 가장 기본적인 알고리즘------mark/clear 알고리즘입니다. 이 알고리즘을 알아낸다면 다음 두 알고리즘은 식은 죽 먹기가 될 것입니다.
먼저 이전 장에서 언급한 루트 검색 알고리즘을 떠올려 보겠습니다. 이는 어떤 개체를 재활용해야 하는지에 대한 문제를 해결할 수 있지만 분명히 프로그램에 포함되어 있기 때문에 가비지 수집에 대한 무거운 책임을 질 수는 없습니다( 프로그램도 우리를 참조합니다. JVM에서 실행되는 JAVA 프로그램이 실행되는 동안 가비지 수집을 수행하려면 GC 스레드가 프로그램의 스레드와 협력하여 실행에 영향을 주지 않고 가비지가 성공적으로 재활용될 수 있도록 해야 합니다. 프로그램의.
이 목표를 달성하기 위해 마크/클리어 알고리즘이 탄생했습니다. 이것이 하는 일은 힙의 사용 가능한 메모리 공간이 고갈되면 전체 프로그램을 중지(세계 중지라고도 함)한 다음 두 가지 작업을 수행하는 것입니다. 첫 번째는 표시이고 두 번째는 항목이 지워집니다.
LZ가 마킹과 클리어링이 각각 어떤 역할을 하는지 자세히 설명해드립니다.
마킹: 마킹 프로세스는 실제로 모든 GC Roots를 순회한 다음 GC Roots가 도달할 수 있는 모든 객체를 활성 객체로 표시하는 것입니다.
지우기: 정리 프로세스는 힙의 모든 개체를 순회하고 표시되지 않은 모든 개체를 지웁니다.
사실 이 두 단계는 특별히 복잡하지도 않고 이해하기도 쉽습니다. LZ는 일반인의 관점에서 표시/지우기 알고리즘을 설명합니다. 프로그램이 실행 중일 때 사용 가능한 메모리가 모두 소모되면 GC 스레드가 트리거되고 프로그램이 일시 중지됩니다. 그런 다음 살아남은 개체가 다시 표시되고 마지막으로 모두 삭제됩니다. 표시되지 않은 개체를 힙에 저장한 다음 프로그램이 다시 실행되도록 합니다.
아래 LZ는 위의 과정을 설명하기 위해 일련의 사진을 만들었습니다. 사진과 함께 이 과정을 직관적으로 살펴보겠습니다.
이 그림은 프로그램 실행 중 모든 개체의 상태를 나타냅니다. 해당 플래그 비트는 모두 0(즉, 표시되지 않음)입니다. 아래 기본값은 표시되지 않은 경우 0입니다. 1 for (marked), 이때 유효 메모리 공간이 소진되었다고 가정하면 JVM은 애플리케이션을 중지하고 GC 스레드를 시작한 다음 루트 검색 알고리즘에 따라 마킹 작업을 시작합니다. 개체는 아래와 같습니다.
보시다시피 루트 검색 알고리즘에 따르면 루트 개체에서 도달할 수 있는 모든 개체는 살아있는 개체로 표시됩니다. 이때 표시의 첫 번째 단계는 다음과 같습니다. 완료되었습니다. 다음으로 정리의 두 번째 단계가 수행되며, 정리가 완료되면 남은 개체와 그 상태는 아래 그림과 같습니다.
보시다시피 표시되지 않은 개체는 재활용되고 지워지는 반면, 표시된 개체는 그대로 유지되며 표시 비트가 0으로 재설정됩니다. 말할 필요도 없이, 중지된 프로그램 스레드를 깨우고 프로그램이 계속 실행되도록 놔두세요.
사실 이 과정은 복잡하지 않고, 아주 간단하다고도 할 수 있죠? 그런데 한 가지 언급할 만한 점이 있는데, 왜 프로그램의 실행을 중단해야 하는가?
이것은 실제로 이해하기 어렵지 않습니다. LZ는 우리 프로그램과 GC 스레드가 함께 실행된다고 가정합니다.
그림에서 가장 오른쪽 객체를 방금 표시했다고 가정해 보겠습니다. 결과적으로 이때 프로그램에는 새로운 객체 B가 생성되고 A 객체는 B 객체에 도달할 수 있습니다. . 그러나 이때 A객체는 마킹되었으므로 B객체의 마크비트는 마킹단계를 놓쳤기 때문에 현재로서는 여전히 0이다. 따라서 위상을 제거하는 다음 차례가 되면 새 객체 B가 하드 제거됩니다. 결과적으로 GC 스레드로 인해 프로그램이 제대로 작동하지 않을 것이라고 상상하는 것은 어렵지 않습니다.
물론 위 결과는 받아들일 수 없습니다. 방금 새 객체를 생성했는데 GC 후에 갑자기 null이 되었습니다. 어떻게 해야 할까요?
지금까지 LZ의 마크/클리어 알고리즘에 대해 소개했습니다. 실제로 알고리즘 원리를 이해하고 나면 단점을 쉽게 이해할 수 있습니다.
1. 우선 효율성이 상대적으로 낮다는 점(재귀 및 전체 힙 개체 순회)이 단점이며, GC 수행 시 애플리케이션을 중지해야 하므로 특히 사용자 경험이 매우 좋지 않습니다. 대화형 애플리케이션의 경우 이는 용납될 수 없습니다. 웹사이트에서 플레이하고 있는데 사이트가 한 시간에 5분 동안 다운된다면 계속 플레이하시겠습니까?
2. 두 번째 주요 단점은 이러한 방식으로 지워진 여유 메모리가 불연속적이라는 점입니다. 이제 죽은 개체가 메모리 구석구석에 무작위로 나타납니다. 지저분하다. 이에 대처하기 위해 JVM은 사용 가능한 메모리 목록을 유지해야 하는데 이는 또 다른 오버헤드입니다. 게다가 배열 객체를 할당할 때 연속적인 메모리 공간을 찾기가 어렵습니다.
어떤 유인원 친구들은 단점을 읽고 "이 알고리즘은 전혀 쓸모가 없는데 LZ는 왜 그런 걸 소개하는 거지?"라고 토할 수도 있습니다.
유인원 친구들아, 하지 마세요. 걱정하세요. 알고리즘에 단점이 있으면 전문가들은 자연스럽게 이를 개선하기 위해 최선을 다할 것입니다. 다음에 소개할 두 가지 알고리즘은 모두 Mark/Clear 알고리즘을 기반으로 최적화되어 있습니다. LZ는 다음번에 구체적인 내용을 여러분과 공유할 것입니다.
이것으로 나눔을 마치겠습니다. 0.0.
위는 JVM 메모리 관리 내용입니다------GC 알고리즘 개선(마크/클리어 알고리즘을 완전히 이해하는 데 5분 소요). 더 많은 관련 내용을 보려면 PHP를 주의하세요. 중국사이트(m.sbmmt.com)!