소개
궁극의 알고리즘이란?
사실 현재 JVM에서 사용하는 알고리즘이지 실제 궁극기는 아닙니다. 아마도 몇 년 후에는 새로운 궁극의 알고리즘이 나올 것이고, 거의 확실하게 하나가 될 것입니다. 왜냐하면 LZ는 고급 사람들의 능력을 믿기 때문입니다.
그럼 세대별 수집 알고리즘은 GC를 어떻게 처리하나요?
객체 분류
이전 장에서 언급했듯이 세대별 수집 알고리즘은 객체의 다양한 특성을 기반으로 하며 실제로 새로운 알고리즘이 생성되지는 않습니다. 세대수집 알고리즘은 네 번째 알고리즘이라기보다는 앞선 세 가지 알고리즘을 실제로 적용한 것이라고 보는 게 더 맞을 것 같다.
먼저 객체의 다양한 특성에 대해 논의해 보겠습니다. 다음으로 LZ와 모두는 이러한 객체에 대해 GC 알고리즘을 선택합니다.
기억 속의 사물은 수명주기에 따라 크게 세 가지로 나눌 수 있습니다. 아래 이름은 모두 LZ의 개인 이름입니다.
1. 일찍 죽는 사물: 태어나고 사라지는 사물, 일반인의 표현으로는 오래 살기도 전에 죽는 사물입니다.
예: 메소드의 지역 변수, 루프 내의 임시 변수 등
2. 노인 불멸 물체: 이 유형의 물체는 일반적으로 더 오래 살고 매우 노년기에도 여전히 살아 있습니다. 그러나 최종 분석에 따르면 노인 불멸 물체는 조만간 죽을 것이 거의 확실하지만 거의 그럴 뿐입니다.
예: 캐시 개체, 데이터베이스 연결 개체, 싱글톤 개체(싱글톤 모드) 등
3. 불멸의 물체: 이러한 물체는 일반적으로 일단 태어나면 거의 항상 불멸의 상태입니다.
예: 스트링 풀(플라이웨이트 모드)의 개체, 로드된 클래스 정보 등
객체에 해당하는 메모리 영역
앞서 메모리 관리를 소개했을 때 JVM에 의한 메모리 분할을 기억하시나요?
위의 세 객체를 메모리 영역에 매핑합니다. 즉, 조기 객체와 불멸 객체는 JAVA 힙에 있고 불멸 객체는 메소드 영역에 있습니다.
이전 장에서 JAVA 힙의 경우 JVM 사양에서는 GC를 구현해야 한다고 말했습니다. 따라서 조기 객체와 불멸 객체의 경우 죽음은 거의 피할 수 없는 결과이지만 거의 불가피합니다. 애플리케이션이 종료될 때까지 살아남는 개체가 있습니다. 그러나 JVM 사양에서는 메서드 영역에서 GC를 요구하지 않으므로 JVM 구현이 메서드 영역에서 GC를 구현하지 않는다고 가정하면 불멸 객체는 진정한 불멸 객체입니다.
불멸 객체의 수명주기가 너무 길기 때문에 세대별 수집 알고리즘은 JAVA 힙, 즉 조기 객체와 오래된 불멸 객체에 맞게 설계되었습니다.
JAVA 힙 객체 재활용(젊은 객체와 오래된 불멸 객체)
위의 분석을 통해 세대별 수집 알고리즘이 JAVA 힙 메모리 재활용, 즉 조기 객체를 어떻게 처리하는지 살펴보겠습니다. 물건과 불멸의 물건의 재활용.
중단된 개체: 이 유형의 개체는 왔다 갔다 하며 생존 시간이 짧습니다. 복제 알고리즘을 사용하기 위한 요구 사항을 아직도 기억하시나요? 즉, 객체 생존율이 너무 높아서는 안 되므로 복제 알고리즘을 사용하는 데는 조기 객체가 가장 적합합니다.
작은 질문: 메모리의 50%가 낭비되면 어떻게 해야 하나요?
답변: 일반적으로 조기 객체의 생존율이 낮기 때문에 메모리의 50%를 free로 사용할 필요는 없습니다. 일반적으로 메모리의 10% 두 개를 free 및 active 범위로 사용하고 나머지 하나를 사용합니다. 메모리의 80%는 새로 생성된 개체에 메모리를 할당하는 데 사용됩니다. GC가 발생하면 활성 범위의 10%와 남아 있는 개체의 나머지 80%가 사용 가능한 범위의 10%로 전송됩니다. 그런 다음 이전 메모리의 90%가 모두 해제됩니다.
이 GC 프로세스를 보다 명확하게 볼 수 있도록 LZ는 다음 다이어그램을 제공합니다.
그림은 각 단계의 세 영역 각각의 메모리 상태를 표시합니다. 그림을 보면 GC 과정을 이해하는 것은 어렵지 않다고 생각합니다.
그러나 LZ가 언급해야 할 두 가지 사항이 있습니다. 첫 번째 요점은 이 방법을 사용하면 메모리의 10%만 낭비된다는 것입니다. 이는 메모리와 GC의 깔끔한 배열을 얻기 때문입니다. 속도. 두 번째 요점은 이 전략의 전제는 살아남은 각 개체가 차지하는 메모리가 이 10% 크기를 초과할 수 없다는 것입니다. 이 크기를 초과하면 추가 개체가 복사되지 않습니다.
위의 예상치 못한 상황, 즉 살아남은 개체가 차지하는 메모리가 너무 큰 경우를 해결하기 위해 전문가들은 JAVA 힙을 두 부분으로 나누어 처리하도록 합니다. 아니면 젊은 세대. 오래되고 불멸의 물건을 저장하는 데 전념하는 나머지 부분을 구세대라고 합니다.
아주 적절한 이름이지 않나요? 오래된 불멸의 물건을 다루는 방법을 살펴 보겠습니다.
오래된 불멸 개체: 이러한 유형의 개체는 대부분이 새로운 세대에서 전달되기 때문에 생존율이 매우 높습니다. 사람과 마찬가지로 오래 살면 늙고 불멸의 존재가 됩니다.
일반적으로 다음 두 가지 상황이 발생하면 개체가 New Generation 영역에서 Old 영역으로 이동됩니다.
1. 새로운 세대의 모든 개체에는 해당 개체의 연령이 특정 수준에 도달하면(연령은 살아남은 GC의 수이며 개체가 각 GC에서 살아남으면 연령이 증가합니다.) 1)에 의해 Old Generation으로 전달되며, 이러한 Old Generation으로의 전달에 대한 age 값은 일반적으로 JVM에서 설정할 수 있다.
2. 새로운 세대에서 살아남은 객체가 차지하는 메모리가 10%를 초과하면 초과된 객체는 Old 세대에 배치됩니다. 이때 구세대는 신세대의 '백업 창고'이다.
오래되고 불멸하는 물체의 특성상 생존율이 너무 높기 때문에 복제 알고리즘을 사용하는 것은 분명히 더 이상 적합하지 않으며, 만약 구세대가 다시 복제 알고리즘을 사용한다면, 백업 창고가 없습니다. 따라서 일반적으로 오래된 불멸 개체에는 표시/구성 또는 표시/지우기 알고리즘만 사용할 수 있습니다.
메서드 영역의 객체 재활용(불멸 객체)
위의 두 상황은 GC 문제의 대부분을 해결했습니다. 왜냐하면 JAVA 힙이 GC의 주요 초점이고 위의 상황이 또한 포함되었습니다. 세대별 컬렉션 알고리즘의 전체 내용이 공개되었으며, 이후의 불멸 개체 재활용은 더 이상 세대별 컬렉션 알고리즘에 포함되지 않습니다.
메소드 영역에는 불멸의 객체가 존재합니다. 우리가 흔히 사용하는 핫스팟 가상 머신(JDK 기본 JVM)에서는 메소드 영역을 영구 생성이라는 애칭으로 부르기도 합니다.
사실 옛날에는 영구세대가 없었어요. 당시에는 영구세대와 구세대가 함께 저장되어 있었는데, 여기에는 JAVA 클래스의 인스턴스 정보와 클래스 정보가 담겨 있었다. 그러나 나중에 클래스 정보 언로드가 거의 발생하지 않는다는 사실이 밝혀져 둘을 분리했습니다. 다행히 이렇게 하면 성능이 상당히 향상됩니다. 그래서 영구세대가 갈라졌습니다.
이 부분의 GC는 "대기 창고"가 없기 때문에 둘 다 표시/지우기 및 표시/구성 알고리즘만 사용할 수 있으므로 이전 세대와 유사한 방법을 사용합니다.
재활용 시기
JVM이 GC를 수행할 때 위의 세 가지 메모리 영역이 매번 함께 재활용되는 것은 아니며 대부분의 경우 재활용은 새로운 세대를 의미합니다. 따라서 GC는 재활용 영역에 따라 일반 GC(Minor GC)와 글로벌 GC(Major GC 또는 Full GC)의 두 가지 유형으로 구분됩니다.
Normal GC(minor GC) : 신세대 영역만을 위한 GC입니다.
글로벌 GC(major GC 또는 Full GC): Old 세대를 위한 GC, 때때로 New 세대를 위한 GC 및 영구 세대를 위한 GC가 동반됩니다.
Old 세대와 영구 세대의 GC 효과는 상대적으로 낮고, 두 세대의 메모리 사용량이 천천히 증가하기 때문에 일반적으로 전역 GC를 트리거하려면 여러 번의 일반 GC가 필요합니다.
결론
위는 JVM 메모리 관리 ------ GC 알고리즘 상세 설명(5분간 궁극의 알고리즘을 가르쳐준다 --- 세대별 모음 알고리즘) 내용, 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!