JDK14 기능 - GC 개선 및 최적화

G1의 NUMA 메모리 할당 최적화

NUMA 소개

NUMA는 Non-Uniform Memory Access Architecture(영어: Non-Uniform Memory Access, 줄여서 NUMA)입니다. 다중 프로세서 컴퓨터용으로 설계된 메모리 아키텍처입니다. 메모리 액세스 시간은 프로세서를 기준으로 한 메모리 위치에 따라 다릅니다. NUMA에서 프로세서는 비로컬 메모리(다른 프로세서에 있는 메모리 또는 프로세서 간에 공유되는 메모리)보다 더 빠르게 자체 로컬 메모리에 액세스할 수 있습니다. 아래 그림과 같이 Node0의 CPU가 Node0의 메모리에 액세스하면 로컬 메모리에 액세스하고, Node1의 메모리에 액세스하면 원격 액세스가 되어 성능이 저하됩니다.

이미지.png

비균일 메모리 액세스 아키텍처의 특징은 다음과 같습니다.

공유 메모리는 물리적으로 분산되어 있으며 이러한 모든 메모리의 집합이 전역 주소 공간입니다. 따라서 프로세서가 이러한 메모리에 액세스하는 데 걸리는 시간이 다르며, 당연히 로컬 메모리에 액세스하는 것이 글로벌 공유 메모리에 액세스하거나 외부 메모리에 원격으로 액세스하는 것보다 빠릅니다. 또한 NUMA의 메모리는 로컬 메모리, 그룹 내 공유 메모리, 전역 공유 메모리 등 계층적일 수 있습니다.

표적

JEP345는 NUMA 인식 메모리 할당을 구현하여 메인프레임에서 G1 성능을 향상시키기를 희망합니다.

점점 더 많은 최신 멀티 소켓 서버에는 NUMA가 있는데, 이는 메모리에서 각 소켓까지의 거리가 동일하지 않으며, 서로 다른 소켓에 메모리에 액세스할 때 성능 차이가 있음을 의미하며, 거리가 길어질수록 대기 시간은 낮아집니다. , 성능이 더 나빠질 것입니다!

G1의 힙은 고정된 크기의 영역 모음으로 구성됩니다. 영역은 일반적으로 물리적 페이지 집합이지만, 큰 페이지를 사용하는 경우(-XX:+UseLargePages를 통해) 여러 영역이 물리적 페이지를 구성할 수 있습니다.

+XX:+UseNUMA 옵션이 지정되면 JVM이 초기화될 때 사용 가능한 총 NUMA 노드 수에 걸쳐 영역이 고르게 분산됩니다.

처음에 영역당 NUMA 노드를 핀치하는 것은 다소 유연하지 않지만 다음과 같은 개선 사항을 통해 완화될 수 있습니다. mutator 스레드에 새 개체를 할당하려면 G1이 새 영역을 할당해야 할 수도 있습니다. 현재 스레드에 바인딩된 NUMA 노드에서 여유 영역을 우선적으로 선택하여 이 작업을 수행하므로 개체는 새 세대에서도 동일한 NUMA 노드에 유지됩니다. 변수에 대한 영역을 할당하는 과정에서 동일한 NUMA 노드에 여유 영역이 없으면 G1은 가비지 수집을 트리거합니다. 평가할 또 다른 아이디어는 가장 가까운 NUMA 노드부터 시작하여 거리순으로 다른 NUMA 노드의 여유 영역을 검색하는 것입니다.

이 기능은 이전 세대의 동일한 NUMA 노드에 개체를 유지하려고 시도하지 않습니다.

JEP 345는 Linux에서만 메모리 관리(메모리 할당)에 대해서만 G1 가비지 수집기에 대한 NUMA 지원을 구현하도록 특별히 설계되었습니다. NUMA 아키텍처에 대한 이러한 지원이 다른 가비지 수집기나 다른 부분(예: 작업 대기열 도용)에도 적용되는지 여부는 불분명합니다.

Serial+CMS, ParNew+Serial Old 지원 중단

유지 관리 및 호환성 테스트 비용으로 인해 Serial+CMS 및 ParNew+Serial Old 두 조합은 JDK8(JEP173)에서 더 이상 사용되지 않는 것으로 선언되었으며 이러한 조합에 대한 지원은 JDK9(JEP214)에서 완전히 취소되었습니다.

이미지.png

ParallelScavenge+SerialOld GC의 GC 조합은 더 이상 사용되지 않음으로 표시됩니다.

이유

이 GC 조합은 코드 유지 관리 작업이 많이 필요하며, 사용 시나리오가 큰 Young 영역과 작은 Old 영역이어야 하기 때문에 거의 사용되지 않으며, 이 경우 SerialOld GC를 사용하여 Old 영역을 수집합니다. 거의 받아들일 수 없습니다.

;Parallelyoung GenerationGC와 SerialOldGC의 조합을 포기했습니다(-XX:+UseParallelGC와 -XX:-UseParallelOldGC가 함께 켜짐). 이제 -XX:+UseParallelGC -XX:-UseParallelOldGC를 사용하거나 -XX:-UseParallelOldGC를 사용하세요. 다음 경고 나타날거야

이미지.png

CMS 삭제

G1이 등장한 이후 CMS는 JDK9에서 더 이상 사용되지 않는 것으로 표시되었습니다.

CMS의 단점

  • 메모리 조각화가 발생하여 동시 지우기 후 사용자 스레드에 사용할 수 있는 공간이 부족해집니다(마크 지우기 알고리즘에 의해 생성되며 마무리 알고리즘으로 해결해야 함).
  • 동시(Concurrent) CMS 수집기를 강조하므로 CPU 리소스에 매우 민감하여 처리량이 감소합니다.
  • CMS 수집기는 부동 쓰레기를 처리할 수 없습니다(사용자 스레드와 쓰레기 수집 스레드가 동시에 실행되고 사용자 스레드는 재활용 중에 새 쓰레기를 생성함).

CMS가 작동을 멈추면 그 대안으로 Serial Old GC가 사용되는데 이는 JVM에서 성능이 가장 낮은 가비지 수집 방법으로 몇 초 또는 심지어 10초 동안 일시 중지될 수 있습니다.

CMS 가비지 컬렉터가 제거되었으며 JDK14에서 -XX:+UseConcMarkSweepGC를 계속 사용하면 오류가 보고되지 않고 경고 경고만 표시됩니다.

warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0

기타 가비지 수집기

G1 콜렉터 핫스팟은 몇 년 동안 기본적으로 사용되었습니다. 또한 두 가지 새로운 GC인 JAVA11의 ZGC와 openJDK12의 Shenandoah를 보았습니다. 후자 두 가지의 주요 기능은 다음과 같습니다. 낮은 일시 중지 시간

Shenandoah는 Oracle에서 공식적으로 릴리스하지 않고 JAVA12의 OpenJDK에서 릴리스합니다.

수집가 이름 영업시간 총 일시중지 시간 최대 일시 정지 시간 평균 정지 시간
셰넌도어 387.602초 320ms 89.79ms 53.01ms
G1 312.052초 11.7초 1.24p 450.12ms
CMS 286.264초 12.78초 4.39초 852.26ms
병렬 청소 260.092초 6.59초 3.04초 823.75ms

macOS 및 Windows의 ZGC

JAVA14 이전에는 ZGC는 Linux만 지원했습니다.

일부 개발, 배포 및 테스트 요구 사항에 따라 ZGC는 JDK14의 macOS 및 Windows에서 지원되므로 많은 데스크톱 애플리케이션이 ZGC의 이점을 누릴 수 있습니다. 아직 실험적인 버전이며 macOS 및 Windows에서 사용할 수 있습니다.

ZGC와 Shenandoah의 목표는 매우 유사합니다. 처리량을 최소화하면서 모든 힙 크기(TB 수준)에 대해 가비지 수집기 일시 중지 시간을 10밀리초 미만으로 제한할 수 있는 낮은 대기 시간을 달성하는 것입니다.

ZGC 컬렉터는 Region 메모리 레이아웃을 기반으로 하는 가비지 컬렉터로 당분간 생성이 없으며 읽기 장벽, 염색 포인터, 메모리 다중 매핑 등의 기술을 사용하여 동시 마크 압축 알고리즘을 구현하는 가비지입니다. 낮은 지연 시간을 주요 목표로 하는 수집기입니다. 이제 macOS와 windows에서 ZGC를 사용하고 싶습니다.방법은 다음과 같습니다.

-XX:+실험적 VM 옵션 잠금 해제 -XX:+ZGC 사용

ZGC에 대한 일부 테스트 데이터

이미지.png

이미지.png

ZGC는 아직 실험 단계이지만 성능이 매우 인상적이며 앞으로는 서버 측 대용량 메모리 및 지연 시간이 짧은 애플리케이션에서 선호되는 가비지 수집기로 사용될 것입니다.

추천

출처blog.csdn.net/qq_28314431/article/details/132939927