1. 개요
이 빠른 자습서에서는 다양한 JVM 가비지 컬렉션 (GC) 구현 의 기본 사항을 보여줍니다 . 또한 애플리케이션에서 특정 유형의 가비지 컬렉션을 활성화하는 방법을 알아 봅니다.
2. 가비지 컬렉션에 대한 간략한 소개
이름에서 가비지 컬렉션 은 메모리에서 가비지를 찾고 삭제하는 것처럼 보입니다 . 그러나 실제로 가비지 콜렉션 은 JVM 힙 공간에서 사용 가능한 모든 오브젝트를 추적하고 사용하지 않는 오브젝트를 제거합니다.
간단히 말해서 GC 는 Mark 및 Sweep이라는 두 가지 간단한 단계로 작동합니다.
- Mark – 가비지 수집기가 사용중인 메모리와 그렇지 않은 메모리를 식별하는 곳입니다.
- Sweep – 이 단계는 "마크"단계에서 식별 된 개체를 제거합니다.
장점 :
- 사용되지 않은 메모리 공간은 GC에서 자동으로 처리하므로 수동 메모리 할당 / 할당 해제 처리가 없습니다.
- Dangling Pointer 를 처리하는 오버 헤드 없음
- 자동 메모리 누수 관리 ( GC 자체 캔에 메모리 누출에 대한 완전한 증거 솔루션을 보장하지, 그러나, 그것의 좋은 부분을 담당)
단점 :
- 이후 JVM은 오브젝트 레퍼런스 생성 / 삭제를 추적 할 수 있고,이 활동은 원래 애플리케이션 외에 더 많은 CPU 파워를 필요로한다. 대용량 메모리가 필요한 요청의 성능에 영향을 미칠 수 있습니다.
- 프로그래머는 더 이상 필요하지 않은 개체를 해제하는 데 할당 된 CPU 시간 일정을 제어 할 수 없습니다.
- 일부 GC 구현을 사용하면 애플리케이션이 예기치 않게 중지 될 수 있습니다.
- 자동화 된 메모리 관리는 적절한 수동 메모리 할당 / 할당 해제만큼 효율적이지 않습니다.
3. GC 구현
JVM에는 네 가지 유형의 GC 구현이 있습니다.
- 직렬 가비지 수집기
- 병렬 가비지 수집기
- CMS 가비지 수집기
- G1 가비지 수집기
3.1. 직렬 가비지 수집기
이것은 기본적으로 단일 스레드에서 작동하므로 가장 간단한 GC 구현입니다. 결과적 으로이 GC 구현은 실행될 때 모든 애플리케이션 스레드를 고정합니다 . 따라서 서버 환경과 같은 다중 스레드 응용 프로그램에서 사용하는 것은 좋지 않습니다.
그러나 QCon 2012에서 트위터 엔지니어들이 Serial Garbage Collector 의 성능에 대해 훌륭한 강연을 했습니다 . 이것은이 수집기를 더 잘 이해하는 좋은 방법입니다.
직렬 GC는 작은 일시 중지 시간 요구 사항이없고 클라이언트 스타일 시스템에서 실행되는 대부분의 응용 프로그램에 대해 선택되는 가비지 수집기입니다. Serial Garbage Collector 를 활성화하려면 다음 인수를 사용할 수 있습니다.
java -XX:+UseSerialGC -jar Application.java
3.2. 병렬 가비지 수집기
JVM 의 기본 GC 이며 처리량 수집기라고도합니다. Serial Garbage Collector 와 달리 이것은 힙 공간을 관리하기 위해 다중 스레드를 사용합니다 . 그러나 GC 를 수행하는 동안 다른 애플리케이션 스레드도 동결 됩니다.
이 GC 를 사용하면 최대 가비지 수집 스레드와 일시 중지 시간, 처리량 및 풋 프린트 (힙 크기)를 지정할 수 있습니다 .
가비지 수집기 스레드 수는 명령 줄 옵션 -XX : ParallelGCThreads = <N> 으로 제어 할 수 있습니다 .
최대 일시 중지 시간 목표 (두 GC 사이의 간격 [밀리 초] )는 명령 줄 옵션 -XX : MaxGCPauseMillis = <N>으로 지정 됩니다.
최대 처리량 목표 (가비지 수집을 수행하는 데 소요 된 시간 대 가비지 수집 외부에 소요 된 시간과 관련하여 측정 됨)는 명령 줄 옵션 -XX : GCTimeRatio = <N>에 의해 지정됩니다 .
-Xmx <N> 옵션을 사용하여 최대 힙 풋 프린트 (프로그램이 실행하는 동안 필요한 힙 메모리 양)를 지정합니다 .
Parallel Garbage Collector 를 활성화하려면 다음 인수를 사용할 수 있습니다.
java -XX:+UseParallelGC -jar Application.java
3.3. CMS 가비지 수집기
동시 마크 스윕 (CMS) 구현은 가비지 콜렉션에 대해 여러 가비지 컬렉터 스레드를 사용합니다. 더 짧은 가비지 컬렉션 일시 중지를 선호하고 애플리케이션이 실행되는 동안 가비지 수집기와 프로세서 리소스를 공유 할 수있는 애플리케이션을 위해 설계되었습니다.
간단히 말해서, 이러한 유형의 GC를 사용하는 애플리케이션은 평균적으로 느리게 응답하지만 가비지 수집을 수행하기 위해 응답을 중지하지 않습니다.
여기서 주목할 점은이 GC 가 동시 적이므로 동시 프로세스가 작동하는 동안 System.gc () 를 사용하는 것과 같은 명시 적 가비지 수집을 호출 하면 Concurrent Mode Failure / Interruption 이 발생한다는 것 입니다.
총 시간의 98 % 이상이 CMS 가비지 수집에 소비되고 힙의 2 % 미만이 복구되면 CMS 수집기 에서 OutOfMemoryError 가 발생합니다 . 필요한 경우 -XX : -UseGCOverheadLimit 옵션 을 명령 줄 에 추가하여이 기능을 비활성화 할 수 있습니다 .
이 콜렉터에는 Java SE 8에서 더 이상 사용되지 않으며 향후 주요 릴리스에서 제거 될 수있는 증분 모드로 알려진 모드도 있습니다.
CMS Garbage Collector 를 활성화하려면 다음 플래그를 사용할 수 있습니다.
java -XX:+UseParNewGC -jar Application.java
Java 9 부터 CMS 가비지 수집기는 더 이상 사용되지 않습니다 . 따라서 JVM은 사용하려고하면 경고 메시지를 출력합니다.
>> java -XX:+UseConcMarkSweepGC --version
Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated
in version 9.0 and will likely be removed in a future release.
java version "9.0.1"
또한 Java 14 는 CMS 지원을 완전히 중단했습니다.
>> java -XX:+UseConcMarkSweepGC --version
OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC;
support was removed in 14.0
openjdk 14 2020-03-17
3.4. G1 가비지 수집기
G1 (Garbage First) Garbage Collector 는 대용량 메모리 공간이있는 다중 프로세서 시스템에서 실행되는 응용 프로그램을 위해 설계되었습니다. JDK7 업데이트 4 및 이후 릴리스 부터 사용할 수 있습니다 .
G1 수집기는 성능 효율성이 더 높기 때문에 CMS 수집기를 대체합니다 .
다른 수집기와 달리 G1 수집기는 힙을 동일한 크기의 힙 영역 집합으로 분할하며, 각 힙은 연속적인 가상 메모리 범위입니다. 가비지 수집을 수행 할 때 G1 은 힙 전체에서 개체의 활성 상태를 확인하기 위해 동시 전역 표시 단계 (즉, 표시 라고하는 1 단계 ) 를 표시 합니다.
마크 단계가 완료된 후 G1 은 대부분 비어있는 영역을 인식합니다. 이 영역에서 먼저 수집되며 일반적으로 상당한 양의 여유 공간을 생성합니다 (예 : Sweeping으로 알려진 2 단계 ). 이 가비지 콜렉션 방법을 가비지 우선이라고 부르는 이유입니다.
G1 Garbage Collector 를 활성화하려면 다음 인수를 사용할 수 있습니다.
java -XX:+UseG1GC -jar Application.java
3.5. Java 8 변경 사항
Java 8u20 은 동일한 문자열의 인스턴스를 너무 많이 생성하여 불필요한 메모리 사용을 줄이기 위해 하나 이상의 JVM 매개 변수를 도입했습니다 . 이렇게 하면 전역 단일 char [] 배열에 중복 문자열 값을 제거하여 힙 메모리를 최적화합니다 .
이 매개 변수는 -XX : + UseStringDeduplication 을 JVM 매개 변수 로 추가하여 활성화 할 수 있습니다 .
4. 결론
이 빠른 자습서에서는 다양한 JVM 가비지 컬렉션 구현과 사용 사례를 살펴 보았습니다 .