프로덕션에서 Java G1 가비지 수집


91

Java 7은 기본적으로 새로운 G1 가비지 콜렉션을 사용하기 때문에 Java가 GC 일시 중지 시간을 "파괴적인"것으로 간주하지 않고 훨씬 더 큰 힙을 처리 할 수 ​​있습니까? 실제로 G1을 프로덕션에 구현 한 사람이 있습니까? 경험은 어땠습니까?

공평하게 말하면, 정말 긴 GC 일시 중지를 본 유일한 시간은 워크 스테이션보다 훨씬 더 큰 힙에 있습니다. 내 질문을 명확히하기 위해; G1은 수백 GB의 힙에 대한 게이트웨이를 열 것인가? 결핵?


15
더 구체적으로 다시 표현할 수 있지만 이것은 끔찍한 질문이 아닙니다. 종결 투표를 할 때 사람들이 "질문이 아님"보다 자신을 더 잘 설명했으면 좋겠습니다.
Bill K

나는 종결하기 위해 투표하지 않았지만 OP가 현재 GC에 대한 그의 불만을 자세히 설명하는 더 객관적인 작업을 수행했으면 좋았을 것입니다. 또한 "Java"는 구현에 대해 말하고있는 반면에 "생산에서 G1 구현"이 무엇을 의미하는지, 특히 나머지 질문의 미래 시제와 함께 무엇을 의미하는지 모르겠습니다. 그것이 Java 7에 있다면 분명히 아무도 그것을 프로덕션에 사용하지 않았습니까?
Pascal Cuoq 2010

6
@Pascal G1은 JDK 6 업데이트 14 이후 JDK에서 사용할 수있는 실험적 기능이었습니다. "G1을 프로덕션에 구현"한다는 것은 그가 실제로 G1을 사용한다는 것을 의미한다고 생각하지만 그다지 어렵지 않습니다. G1이 Java가 아니라 JDK 7의 일부라는 데 동의하지만 Google에서 Java 7을 검색하면 JDK 7 홈페이지가 첫 번째 결과로 반환되며 두 용어가 서로 바꿔서 사용되는 경우가 많습니다. @Benju 나는 현재 JDK에서 G1으로 얻은 결과를 실험적이므로 신뢰하지 않을 것입니다. 지금부터 공식 릴리스로 많은 것이 바뀔 수 있습니다.
teto 2010

2
업데이트 1,2 및 3을 포함한 JDK 7은 기본적으로 G1 gc를 사용하지 않는 것 같습니다. 당신은있는 jinfo -flag UseG1GC PID하여 chect 수
조지

답변:


34

G1의 요점은 최대 일시 중지 시간 목표를 지정할 수있는 지점까지도 일시 중지 시간이 더 짧다는 것 같습니다.

가비지 수집은 단순한 "이봐, 꽉 찼습니다. 모든 것을 한 번에 옮기고 다시 시작합시다."거래가 더 이상 아닙니다. 환상적으로 복잡한 다단계 백그라운드 스레드 시스템입니다. 일시 중지없이 백그라운드에서 대부분의 유지 관리를 수행 할 수 있으며, 대부분의 개체가 생성 된 직후 죽는다고 가정하는 것과 같이 런타임시 시스템의 예상 패턴에 대한 지식을 사용하여 도움을줍니다.

GC 일시 중지 시간은 향후 릴리스에서 악화되지 않고 계속 개선 될 것입니다.

편집하다:

다시 읽을 때 Java를 매일 사용한다는 생각이 들었습니다 .Eclipse, Azureus 및 내가 개발하는 앱은 잠시 멈춘 이후로 오랜만이었습니다. 중요한 일시 중지는 아니지만 전혀 일시 중지를 의미합니다.

Windows 탐색기를 마우스 오른쪽 버튼으로 클릭하거나 (가끔) 특정 USB 하드웨어를 연결할 때 일시 중지되는 것을 보았습니다.하지만 Java는 전혀 사용하지 않습니다.

GC는 여전히 누군가에게 문제가 되나요?


동의 - 나도 의도적으로했거나 실수로 대규모 병렬 가비지 생성 코드를 자극 할 때 내가 GC 일시 정지를 본 적이있는 유일한 시간이 .....입니다
mikera

28
예, GC는 특히 대규모 테너 드 세대에서 큰 힙 (> 16GB)을 처리하기 시작할 때 여전히 매우 문제가됩니다.
The Alchemist

2
@ the-alchemist 와우, 몇 번지나 가면서 귀하의 의견을 보았고 16GB라고 말한 것이 저에게 놀랐습니다! 이로 인해 엄청난 지연이 발생할 수 있다는 것이 정확하다고 확신하지만 모든 스와핑을 비활성화했는지 확인하고 싶습니다. 대용량 메모리 시스템에서 어떤 (GC는 매우 스왑 쌀쌀하기 때문에) 자바의 스와핑은 절대적으로 시스템을 죽일 것이다. 나는 당신이 이미 이것을했다고 확신하지만, 나는 그것을 언급하고 싶었습니다. 왜냐하면 그것은 엄청난 차이를 만들 것이기 ​​때문입니다. 램이 그렇게 많은 PC를 본 적이 없습니다. 얼마나 가지고 계십니까? 32g?
Bill K

8
예, GC는 TP99.9 (이상) 한도를 개선하기가 매우 어렵다는 점에서 서비스에 문제가 있습니다. 특히 "오래된 세대"GC는 JVM (및 서비스)을 몇 초 동안 정지시키는 죽음의 함정일 수 있습니다. 일반적으로 한 자릿수 (또는 낮은 두 자릿수) 밀리 초로 요청을 처리하는 서비스의 경우 이는 문제가됩니다. 그만한 가치가있는 것은 Amazon의 Simple Queue 서비스에서 사용하는 백엔드 스토리지의 실질적인 문제였습니다 (AWS 내부이기 때문에 많은 세부 정보로 이동할 수 없음).
StaxMan 2010

21
GC의 성가신 점은 Azul이 프로세서 메모리 하드웨어를 매우 영리하게 사용하여 눈에 띄는 일시 중지 시간없이 수백 기가 바이트에 쉽게 대처할 수있는 독창적 인 GC 알고리즘 (Azul C4)을 몇 년 전에 발명했다는 것입니다. 그러나 아무도 이것을 알지 못하며 운영 체제의 지원이 필요하기 때문에 곧 주요 Java 버전에서 구현되지 않을 것입니다. 그리고 운영 체제 공급 업체는 사람들이 알고리즘에 대해 알고 운영 체제 공급 업체에 압력을 가할 때까지 아무것도하지 않습니다. azulsystems.com/zing/pgc , managedruntime.org
Hans-Peter Störr

58

나는 무거운 응용 프로그램으로 테스트했습니다. 60-70GB는 힙에 할당되고 20-50GB는 언제든지 사용됩니다. 이러한 종류의 응용 프로그램을 사용하면 마일리지가 다를 수 있다고 말하는 것은 과소 평가입니다. Linux에서 JDK 1.6_22를 실행하고 있습니다. 부 버전은 중요합니다. 약 1.6_20 이전에는 임의의 NullPointerExceptions를 유발하는 G1 버그가있었습니다.

나는 당신이 대부분의 시간에 주어진 일시 중지 목표를 유지하는 것이 매우 좋다는 것을 발견했습니다. 기본값은 100ms (0.1 초) 일시 중지로 보이며 그 절반을 수행하도록 지시했습니다 (-XX : MaxGCPauseMillis = 50). 그러나 메모리가 실제로 부족 해지면 패닉 상태가되고 가비지 컬렉션을 완전히 중지합니다. 65GB를 사용하면 30 초에서 2 분 정도 걸립니다. (CPU 수는 아마도 차이를 만들지 않을 것입니다. 아마도 버스 속도에 의해 제한 될 것입니다.)

CMS (기본 서버 GC는 아니지만 웹 서버 및 기타 실시간 애플리케이션 용이어야 함)와 비교할 때 일반적인 일시 중지는 훨씬 더 예측 가능하고 훨씬 더 짧게 만들 수 있습니다. 지금까지 나는 엄청난 멈춤에 대해 CMS에 더 나은 운을 보였지만 그것은 무작위 일 수있다. 24 시간마다 몇 번만보고 있습니다. 현재 내 프로덕션 환경에서 어느 것이 더 적합한 지 잘 모르겠지만 아마도 G1 일 것입니다. 오라클이 계속 튜닝한다면 G1이 궁극적으로 확실한 승자가 될 것이라고 생각합니다.

기존 가비지 수집기에 문제가 없다면 지금 당장 G1을 고려할 이유가 없습니다. GUI 응용 프로그램과 같이 지연 시간이 짧은 응용 프로그램을 실행하는 경우 MaxGCPauseMillis가 매우 낮게 설정된 G1이 올바른 선택 일 것입니다. 배치 모드 애플리케이션을 실행하는 경우 G1은 아무것도 사지 않습니다.


14

프로덕션에서 G1을 테스트하지는 않았지만 GC가 "엄청난"힙이없는 케이스에 대해 이미 문제가 있다고 생각했습니다. 특히 2 또는 4 기가 만있는 서비스는 GC에 의해 심각한 영향을받을 수 있습니다. 젊은 세대의 GC는 일반적으로 한 자릿수 밀리 초 (또는 최대 두 자릿수)로 끝나므로 문제가되지 않습니다. 그러나 구세대 컬렉션은 1 기가 이상의 구세대 크기로 몇 초가 걸리기 때문에 훨씬 더 문제가 많습니다.

이제 : 이론상 CMS는 대부분의 작업을 동시에 실행할 수 있으므로 많은 도움이 될 수 있습니다. 그러나 시간이 지남에 따라이를 수행 할 수없고 "세상을 중지"컬렉션으로 돌아 가야하는 경우가 있습니다. 그리고 그 일이 발생하면 (예를 들어, 1 시간 후-자주는 아니지만 너무 자주), 글쎄, 당신의 빌어 먹을 모자를 붙잡 으십시오. 1 분 이상 걸릴 수 있습니다. 이는 최대 대기 시간을 제한하려는 서비스에서 특히 문제가됩니다. 요청을 처리하는 데 25 밀리 초가 걸리는 대신 이제 10 초 이상이 걸립니다. 모욕에 상처를 입히기 위해 클라이언트는 종종 요청 시간을 초과하고 재 시도하여 추가 문제 (일명 "똥 폭풍")로 이어집니다.

이것은 G1이 많은 도움을 주길 바랬던 영역입니다. 저는 스토리지 및 메시지 발송을위한 클라우드 서비스를 제공하는 대기업에서 일했습니다. 그리고 우리는 CMS를 사용할 수 없었습니다. 대부분의 경우 병렬 품종보다 더 잘 작동했지만 이러한 붕괴가 있었기 때문입니다. 그래서 약 한 시간 동안 일이 좋았습니다. 그런 다음 물건이 팬에 부딪 혔습니다. 서비스가 클러스터를 기반으로했기 때문에 한 노드가 문제가 발생했을 때 다른 노드가 일반적으로 뒤따 랐습니다 (GC로 인한 시간 초과로 인해 다른 노드가 노드가 충돌 한 것으로 믿고 경로를 다시 지정하기 때문입니다).

나는 GC가 앱의 문제라고 생각하지 않으며 클러스터되지 않은 서비스조차도 영향을 덜받는다고 생각합니다. 그러나 점점 더 많은 시스템이 클러스터링되고 (특히 NoSQL 데이터 저장소 덕분에) 힙 크기가 증가하고 있습니다. OldGen GC는 힙 크기와 매우 선형 적으로 관련되어 있습니다 (즉, 힙 크기를 두 배 이상 늘리면 GC 시간이 두 배가되고 라이브 데이터 세트의 크기도 두 배가된다고 가정).


13

Azul의 CTO 인 Gil Tene은 가비지 수집과 관련된 문제에 대한 멋진 개요와 Java 가비지 수집의 이해 및 이에 대해 할 수있는 작업 프레젠테이션 에서 다양한 솔루션에 대한 검토를 제공합니다 .이 문서에는 http : // www.infoq.com/articles/azul_gc_in_detail .

Zing JVM에있는 Azul의 C4 가비지 수집기는 병렬 및 동시 적이며 새로운 세대와 이전 세대 모두에 동일한 GC 메커니즘을 사용하여 동시에 작동하고 두 경우 모두 압축합니다. 가장 중요한 것은 C4가 세상을 멈출 수 없다는 것입니다. 모든 압축은 실행중인 응용 프로그램과 동시에 수행됩니다. 우리는 고객이 매우 큰 (수백 GBytes) 실행 중이며 최악의 경우 GC 일시 중지 시간이 10msec 미만이고 애플리케이션에 따라 종종 1-2msec 미만의 시간이 소요됩니다.

CMS 및 G1의 문제점은 어느 시점에서 Java 힙 메모리를 압축해야하고 이러한 가비지 수집기 모두 압축을 수행하기 위해 세계 / STW를 중지 (즉, 응용 프로그램 일시 중지)해야한다는 것입니다. 따라서 CMS와 G1은 STW 일시 중지를 푸시 할 수 있지만 제거하지는 않습니다. 그러나 Azul의 C4는 STW 일시 중지를 완전히 제거하므로 Zing이 거대한 힙 크기에서도 GC 일시 중지가 낮은 이유입니다.

그리고 이전 답변에서 작성한 진술을 수정하기 위해 Zing은 운영 체제를 변경할 필요가 없습니다. 수정되지 않은 Linux 배포판에서 다른 JVM처럼 실행됩니다.


3
Azul의 C4가 당신이 말한 것을 어떻게 달성했는지, 왜 Sun이나 Oracle이 할 수 없는지 궁금합니다. 큰 비밀이 있습니까 아니면 이것은 일종의 절충안입니까?
조지

5
Azul의 C4는 Azul의 하드웨어 컴퓨팅 어플라이언스 (엔터프라이즈 Java 앱을 실행하기 위해 구축 된 특수 프로세서를 사용)에서 유래 된 매우 독특한 기술을 가지고 있으며 Linux를 실행하는 일반 x86 서버에서 실행되도록 진화했습니다. 다른 모든 엔터프라이즈 급 가비지 수집기 (Oracle이든 IBM이든)는 언젠가는 중지를해야합니다 .Azul의 C4의 고유 한 속성은 이러한 문제가있는 STW 중지를 절대 수행하지 않는다는 것입니다. 궁금하다면 C4 수집가의 발명가가 작동 원리 에 대한 논문을 발표했습니다 : dl.acm.org/citation.cfm?id=1064988 .
Scott Sellers

Scott, 여기 blog.mikemccandless.com/2012/07/… 에서 Azul이 JVM 사용을 위해 메모리를 미리 할당하는 커널 모듈을 제공한다고 읽었습니다 . 사실이 아닙니까? 참이면 커널 수정은 많지 않지만 여전히 수정입니다.
Dan Pritts 2013

4
George, 두 단어 : 특허 보호. Dan, Zing을 구매할 때 지불하는 비용 중 일부는 지원 담당자가 애플리케이션에 맞게 조정하도록하는 것입니다. 여기에는 전체 시스템 메모리 사용량 할당도 포함됩니다. 커널 모듈 자체는 가비지 수집중인 메모리 블록에 대한 쓰기를 방지합니다. 이것이 "일시 중지되지 않는"비밀 소스입니다. 스레드는 해당 블록 중 하나에 쓰려고 할 때만 일시 중지 한 다음 해당 블록을 압축 할 수있을만큼만 일시 중지합니다.
David Leppik 2014 년

13

우리는 거의 2 년 동안 이미 G1GC를 사용하고 있습니다. 미션 크리티컬 트랜잭션 처리 시스템에서 뛰어난 성능을 발휘하며 높은 처리량, 낮은 일시 중지, 동시성 및 최적화 된 대용량 메모리 관리에 대한 훌륭한 지원임을 입증했습니다.

다음 JVM 설정을 사용하고 있습니다.

-server -Xms512m -Xmx3076m -XX:NewRatio=50 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000 -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime

업데이트 됨

-d64 -server -Xss4m -Xms1024m -Xmx4096m -XX:NewRatio=50 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:-DisableExplicitGC -XX:+AggressiveOpts -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods -XX:ReservedCodeCacheSize=48m -XX:+UseStringCache -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000

5
Java 8에서는 -XX : + UseCompressedOops 또는 -XX : + DoEscapeAnalysis를 설정할 필요가 없으며, 부스는 기본적으로 켜져 있습니다. 참조 : docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
Mirko Ebert

8

G1 수집기는 전체 수집의 영향을 줄입니다. 이미 전체 컬렉션의 필요성을 줄인 애플리케이션이있는 경우 Concurrent map Sweep 컬렉터도 마찬가지로 좋으며 경험상 마이너 컬렉션 시간이 더 짧습니다.


"G1의 프로덕션 사용은 Java 지원 계약을 구매 한 경우에만 허용됩니다.", groups.google.com/forum/#!topic/javaposse/Vm0a4H-QY54 , 그래서 그것은 신화입니까?
크리스토프 후씨

1
@ChristopheRoussy 이것이 더 이상 사실인지 모르겠습니다.
Peter Lawrey


5

최근 나는

JDK 1.7.45를 사용하는 서버에서 4G 힙 및 8 코어 프로세서를 사용하는 CMS에서 G1GC로 .

(JDK 1.8.x G1GC는 1.7보다 선호되지만 일부 제한으로 인해 1.7.45 버전을 고수해야합니다)

아래의 주요 매개 변수를 구성하고 다른 모든 매개 변수를 기본값으로 유지했습니다.

-XX:G1HeapRegionSize=n, XX:MaxGCPauseMillis=m, -XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n apart from -Xms and -Xmx

이러한 매개 변수를 미세 조정하려면이 오라클 기사를 참조하십시오.

주요 관찰 :

  1. 메모리 사용량은 CMS의 최고 및 최저와 달리 G1GC와 일치합니다.
  2. 최대 GC 일시 중지 시간은 CMS에 비해 짧습니다.
  3. 가비지 수집에 소요되는 시간은 CMS에 비해 G1GC에서 약간 높습니다.
  4. 주요 컬렉션의 수는 CMS에 비해 거의 무시할 수 있습니다.
  5. CMS에 비해 부수적 컬렉션의 수가 더 높습니다.

그러나 여전히 Max GC 일시 중지 시간이 CMS보다 짧아서 기쁩니다. Max GC 일시 중지 시간을 1.5 초로 설정했으며이 값은 아직 교차하지 않았습니다.

관련 SE 질문 :

G1에 대한 Java 7 (JDK 7) 가비지 콜렉션 및 문서


4

CMS는 유지 된 개체를 누적하지 않고 실행하는 경우에도 성능이 느리게 저하 될 수 있습니다. 이것은 G1이 피할 수있는 메모리 조각화 때문입니다.

유료 지원으로 만 사용할 수있는 G1에 대한 신화는 그저 신화입니다. Sun과 현재 Oracle은 JDK 페이지에서이를 명확히했습니다.


4

G1 GC는 더 잘 작동해야합니다. 그러나 -XX : MaxGCPauseMillis를 너무 공격적으로 설정하면 가비지가 너무 느리게 수집됩니다. 이것이 David Leppik의 예에서 전체 GC가 트리거 된 이유입니다.


4

Terracotta Big Memory 프로젝트에서 G1 Garbage Collector를 방금 구현했습니다. 다양한 유형의 수집기에서 작업하는 동안 G1은 600ms 미만의 응답 시간으로 최상의 결과를 제공했습니다.

테스트 결과 (총 26 개)는 여기 에서 확인할 수 있습니다.

도움이되기를 바랍니다.


3

최근 Twicsy의 일부를 128GB RAM이있는 새 서버로 마이그레이션하고 1.7을 사용하기로 결정했습니다. 1.6에서 사용한 것과 동일한 메모리 설정을 모두 사용하기 시작했습니다 (500MB 힙에서 최대 15GB까지 다양한 작업을 실행하는 여러 인스턴스가 있으며 이제는 40GB의 새 인스턴스가 있음). 전혀 작동하지 않았습니다. . 1.7은 1.6보다 더 많은 힙을 사용하는 것으로 보이며 처음 며칠 동안 많은 문제를 경험했습니다. 다행히도 작업 할 RAM이 많았고 대부분의 프로세스에서 RAM을 올렸지 만 여전히 몇 가지 문제가있었습니다. 내 일반적인 MO는 최대 힙이 몇 기가 바이트 인 경우에도 16m의 매우 작은 최소 힙 크기를 사용한 다음 증분 GC를 켜는 것이 었습니다. 이것은 일시 중지를 최소한으로 유지했습니다. 하지만 지금은 작동하지 않습니다. 최소 크기를 평균적으로 힙에서 사용할 것으로 예상하는 크기로 늘려야했습니다. 그리고 그것은 아주 잘 작동했습니다. 여전히 증분 GC가 켜져 있지만없이 시도 할 것입니다. 지금은 멈추지 않고 모든 것이 매우 빠르게 실행되는 것 같습니다. 그래서 이야기의 교훈은 당신의 기억 설정이 1.6에서 1.7로 완벽하게 번역 될 것이라고 기대하지 않는다는 것입니다.


2

G1은 응용 프로그램을 훨씬 더 민첩하게 만듭니다. 응용 프로그램의 지연 시간이 증가합니다. 응용 프로그램을 "소프트 실시간"으로 명명 할 수 있습니다. 이는 두 종류의 GC 실행 (소형 마이너 실행 및 Tenured Gen에서 큰 실행)을 동일한 크기의 작은 실행으로 대체하여 수행됩니다.

자세한 내용은 http://geekroom.de/java/java-expertise-g1-fur-java-7/을 참조하십시오.


1

저는 크고 작은 힙에 대해 Java로 작업하고 있으며 제약 조건이 다른 것보다 더 엄격 할 수 있으므로 GC 및 Full GC에 대한 질문이 매일 나타납니다. 특정 환경에서는 0.1 초의 scavenger GC 또는 Full GC, kill 단순히 fonctionnalité이며 미세한 구성과 기능이 중요합니다 (CMS, iCMS 등 ... 목표는 거의 실시간 처리로 가능한 최상의 응답 시간을 갖기 위해 여기에 있습니다 (여기서 실시간 처리는 종종 25ms 임). 따라서 기본적으로 GC 인체 공학 및 휴리스틱의 개선 사항은 환영합니다!


1

저는 Java 8 및 Groovy (Java 8)에서도 G1GC를 사용하고 있으며 다양한 종류의 워크로드를 수행하고 있으며 전반적으로 G1GC는 다음과 같이 작동합니다.

  • 메모리 사용량이 매우 낮습니다. 예를 들어 기본 Java 설정에 비해 500MB 대신 100MB

  • 응답 시간이 일관되고 매우 낮습니다.

  • 기본 설정과 G1GC 간의 성능은 최악의 시나리오에서 G1GC를 사용할 때 20 % 느려집니다 (조정없이 단일 스레드 응용 프로그램). 좋은 응답 시간과 낮은 메모리 사용량을 고려하지 않습니다.

  • 멀티 스레드 인 Tomcat에서 실행하면 전체 성능이 30 % 향상되고 메모리 사용량이 훨씬 낮아지고 응답 시간도 훨씬 줄어 듭니다.

따라서 전반적으로 실제로 다양한 워크로드를 사용할 때 G1GC는 다중 스레드 애플리케이션을위한 Java 8 용 매우 좋은 수집기이며 단일 스레드의 경우에도 몇 가지 이점이 있습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.