[소개] 2017년이지만 대부분의 개발자들에게는 여전히 두 가지가 미스터리입니다. 바로 가비지 컬렉션과 이성(코더들이 또다시 비웃음을 받고 있습니다)입니다. 후자에 대해서는 잘 모르기 때문에 전자에 대해 이야기해볼까 하는 생각이 들었습니다.
2017년이지만 대부분의 개발자에게는 두 가지가 여전히 미스터리입니다. 가비지 수집과 이성(코더가 또다시 비웃음을 받고 있습니다)입니다. 저는 후자에 대해 잘 모르기 때문에 전자에 대해 이야기해 볼까 합니다. 특히 Java 8이 등장하면서 이 분야에 많은 변화와 개선이 일어났는데, 그 중 가장 중요한 것은 다음과 같습니다. 영구 생성(PermGen) 제거 및 몇 가지 흥미로운 새 최적화(나중에 언급됨)
가비지 수집이라고 하면 많은 사람들이 그 개념을 이해하고 일상 프로그래밍에 적용하고 있습니다. 그래도 우리가 잘 이해하지 못하는 부분이 많고, 바로 거기서 고통이 옵니다. JVM에 대한 가장 큰 오해는 가비지 수집기가 하나만 있는데 실제로는 각기 장단점이 있는 4개의 서로 다른 수집기가 있다는 것입니다. JVM은 자동으로 하나를 선택하지 않으며 수집기에 따라 처리량 및 애플리케이션 일시 중지 시간에 상당한 차이가 발생할 수 있으므로 선택은 귀하와 나에게 달려 있습니다.
이 네 가지 수집 알고리즘의 공통점은 모두 세대별로 관리된다는 것입니다. 즉, 관리되는 힙을 여러 영역으로 나눈다는 의미입니다. 힙에는 개체가 많이 있다고 가정합니다. 수명주기는 매우 짧고 빠르게 재활용할 수 있습니다. 이 주제에 대해 많은 소개가 있었기 때문에 여기에서는 이러한 다양한 알고리즘과 그 장점과 단점에 대해 직접적으로 이야기할 계획입니다.
직렬 수집기는 주로 단일 스레드 환경(예: 32비트 또는 Windows)에 사용되므로 사용을 고려하지 않을 것입니다. 더 작은 힙. 이 수집기는 작동 중일 때 모든 애플리케이션 스레드를 정지시켜 서버측 애플리케이션에서 사용할 수 없도록 만듭니다.
사용방법: -XX:+UseSerialGC JVM 매개변수를 켜서 사용할 수 있습니다.
다음은 병렬 수집기(Parallel 수집기)입니다. 이는 JVM의 기본 수집기입니다. 이름에서 알 수 있듯이 가장 큰 장점은 여러 스레드를 사용하여 힙을 스캔하고 압축한다는 것입니다. 단점은 마이너 GC인지 전체 GC인지에 관계없이 애플리케이션 스레드를 일시 중지한다는 것입니다. 병렬 수집기는 일시 중지를 허용하고 수집기로 인해 발생하는 CPU 오버헤드를 줄이려고 시도하는 애플리케이션에 가장 적합합니다.
병렬 컬렉터 다음에는 CMS 컬렉터(concurrent-mark-sweep)가 있습니다. 이 알고리즘은 여러 스레드(동시)를 사용하여 힙을 스캔하고 더 이상 사용되지 않으며 재활용(스윕)할 수 있는 개체를 표시합니다. 이 알고리즘은 두 가지 상황에서 "세계 중지" 모드로 들어갑니다. 루트 개체(이전 세대의 스레드 진입점 또는 정적변수의 초기 표시를 수행할 때 개체는 도달함) 그리고 이 알고리즘이 동시에 실행될 때 애플리케이션은 힙의 상태를 변경하여 다시 돌아가 표시된 객체가 올바른지 다시 확인해야 합니다.
이 컬렉터를 사용하면서 가장 큰 문제점은 프로모션 실패에 직면하게 된다는 점입니다. 이는 신세대와 구세대를 재활용할 때 경쟁 조건이 발생하는 상황을 말합니다. Collector가 Young 객체를 Old Generation으로 승격해야 하고 현재 Old Generation에 추가 공간이 없으면 먼저 STW(Stop The World) 전체 GC만 수행할 수 있습니다. 이것이 올바른 상황입니다. CMS가 피하고 싶은 것. 이런 일이 발생하지 않도록 하려면 이전 세대의 크기를 늘리거나(또는 전체 힙의 크기를 늘려야 함) 객체 할당 속도와 경쟁할 수 있도록 일부 백그라운드 스레드를 수집기에 할당해야 합니다. .
이 알고리즘의 또 다른 단점은 병렬 수집기보다 CPU 리소스를 더 많이 사용한다는 것입니다. 여러 스레드를 사용하여 검색 및 재활용을 수행하므로 애플리케이션이 계속해서 더 높은 수준의 처리량을 제공할 수 있습니다. 대부분의 장기 실행 프로그램의 경우 애플리케이션 일시 중단은 매우 해롭습니다. 이때 CMS 리사이클러 사용을 고려할 수 있습니다. 그러나 이 알고리즘은 기본적으로 활성화되어 있지 않습니다. 이를 활성화하려면 XX:+UseConcMarkSweepGC를 지정해야 합니다. 힙이 4G보다 작고 애플리케이션 일시 중단을 방지하기 위해 더 많은 CPU 리소스를 할당하려는 경우 이 수집기를 선택해야 합니다. 그러나 힙이 4G보다 큰 경우 마지막 항목인 G1 수집기를 사용하는 것이 좋습니다.
G1(가비지 우선) 컬렉터는 JDK 7update 4에서 처음 도입되었습니다. 디자인 목표는 4GB보다 큰 힙을 더 효과적으로 지원하는 것입니다. G1 수집기는 힙을 1MB에서 32MB 크기 범위의 영역으로 나누고 여러 백그라운드 스레드를 사용하여 이를 스캔합니다. G1 수집기는 가장 많은 쓰레기가 포함된 영역을 먼저 스캔합니다. 이는 이름의 유래입니다(Garbage first). 이 수집기는 -XX:UseG1GC 플래그를 사용하여 활성화할 수 있습니다.
이 전략은 백그라운드 스레드가 쓸모 없는 객체 검색을 완료하기 전에 힙이 소진될 가능성을 줄입니다. 이 경우 수집기는 애플리케이션을 일시 중지해야 하며 이로 인해 STW 재활용이 발생하게 됩니다. G1의 또 다른 이점은 항상 힙을 압축하는 반면 CMS 수집기는 전체 GC 중에만 이 작업을 수행한다는 것입니다.
지난 몇 년 동안 Dadu는 논란의 여지가 있는 분야였습니다. 많은 개발자가 단일 시스템 단일 JVM 모델 에서 단일 시스템 다중 JVM 마이크로서비스 및 구성 요소화 건축. 이는 애플리케이션 구성 요소 격리, 배포 단순화, 애플리케이션 클래스를 메모리에 다시 로드하는 오버헤드 방지(Java 8에서 개선됨) 등 다양한 요소에 의해 주도됩니다. 그러나 이 작업의 주된 희망은 대규모 GC에서 긴 "세계를 중지"하는 일시 중지(대규모 컬렉션 중 완료하는 데 몇 초가 소요됨)를 방지하는 것입니다. Docker
와 같은 컨테이너 기술을 사용하면 동일한 물리적 시스템에 여러 애플리케이션을 쉽게 배포할 수 있습니다. Java 8 업데이트 20에 도입된 뛰어난 최적화는문자열 중복 제거)입니다. 문자열(내부 문자[]배열 포함)이 대부분의 힙 공간을 차지하므로 이 새로운 최적화는 G1 수집기가 힙에서 반복되는 문자열을 식별하고 동일한 내부 문자를 가리킬 수 있도록 설계되었습니다. [] 배열은 동일한 문자열의 여러 복사본을 방지하여 힙 사용을 비효율적으로 만듭니다. -XX:+UseStringDeduplication JVM 매개변수를 사용하여 이 기능을 사용해 볼 수 있습니다. Java 8 및 영구 생성
Java 8의 가장 큰 변화는 원래 클래스 메타데이터, 상주 문자열 및 정적 변수를 위한 공간을 할당하는 데 사용되었던 영구 생성이 제거된 것입니다. . 과거에는 개발자가 많은 수의 클래스를 로드하는 애플리케이션에 대해 힙 비율을 구체적으로 최적화하고 조정해야 했습니다. 이는 수년 동안 사실이었고 많은 OutOfMemory 예외의 원인이므로 JVM이 인계받는 것이 좋습니다. 그럼에도 불구하고 개발자가 애플리케이션을 다른 JVM으로 분리할 가능성을 그 자체로 줄이지는 않습니다. 각 수집기에는 조정을 위한 다양한 스위치와 옵션이 있으며, 이는 애플리케이션의 특정동작
에 따라 처리량을 늘리거나 줄일 수 있습니다.위 내용은 다양한 Java 가비지 수집기의 비교 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!