Üretimde Java G1 çöp toplama


92

Java 7 varsayılan olarak yeni G1 çöp toplamayı kullanacağına göre, Java sözde "yıkıcı" GC duraklatma süreleri olmadan çok daha büyük bir yığın işleyebilecek mi? Üretimde G1'i gerçekten uygulayan oldu mu, deneyimleriniz nelerdi?

Adil olmak gerekirse, gerçekten uzun GC duraklamalarını gördüğüm tek zaman, bir iş istasyonunun sahip olabileceğinden çok daha fazla, çok büyük yığınlar üzerinde. Soruma açıklık getirmek için; G1, yüzlerce GB'lik yığınlara ağ geçidini açacak mı? TB?


16
Daha spesifik olarak yeniden ifade edilebilecek olsa da, bu korkunç bir soru değil. İnsanların kapanış için oy verirken kendilerini "Soru değil" den daha iyi açıklamalarını isterdim.
Bill K

Kapatmak için oy vermedim, ancak OP'nin mevcut Genel Kurul ile ilişkilerini detaylandırmak için daha objektif bir iş yapmasını diledim. Ayrıca, "Java" bir uygulamadan bahsederken bir dildir ve "üretimde G1'in uygulanması" nın ne anlama geldiğini bilmiyorum, özellikle de sorunun geri kalan kısmıyla. Java 7'de olacaksa, üretimde hiç kimse kullanmamış mı?
Pascal Cuoq

6
@Pascal G1, JDK 6 güncellemesinden bu yana JDK'da bulunan deneysel bir özellikti. "G1'i üretimde uygulamakla", aslında onu kullanmayı kastettiğini düşünüyorum, tahmin etmek o kadar da zor değil. Ve G1'in Java'nın değil, JDK 7'nin bir parçası olduğunu kabul etsem de, Google'da Java 7 araması, ilk sonuç olarak JDK 7 ana sayfasını döndürüyor ve her iki terim de sıklıkla birbirinin yerine kullanılıyor. @Benju Deneysel olduğu için mevcut JDK'da G1 ile elde edilen sonuçlara güvenmem, şu andan itibaren resmi sürüme birçok şey değişebilir.
teto

2
Görünüşe göre 1,2 ve 3 numaralı güncellemeleri içeren JDK 7 varsayılan olarak G1 gc'yi kullanmıyor. Jinfo -flag UseG1GC pid
George

Yanıtlar:


34

G1'in amacı, maksimum duraklama süresi hedefi belirleyebildiği noktaya kadar bile daha küçük duraklama sürelerine sahip olmak gibi görünüyor.

Çöp toplama sadece basit bir "Hey, dolu, hadi her şeyi bir kerede taşıyalım ve baştan başlayalım" işi değil artık - fevkalade karmaşık, çok seviyeli, arka planda işleyen bir sistem. Bakımının çoğunu arka planda hiç duraklama olmadan yapabilir ve aynı zamanda, çoğu nesnenin oluşturulduktan hemen sonra öldüğünü varsaymak gibi, yardımcı olmak için çalışma zamanında sistemin beklenen kalıpları hakkındaki bilgileri kullanır.

Gelecekteki sürümlerle birlikte GC duraklatma sürelerinin kötüleşmeye değil iyileşmeye devam edeceğini söyleyebilirim.

DÜZENLE:

Yeniden okurken Java'yı günlük olarak kullandığımı fark ettim - Eclipse, Azureus ve geliştirdiğim uygulamalar ve bir duraklama gördüğümden bu yana UZUN ZAMANDA oldu. Önemli bir duraklama değil, ama herhangi bir duraklama demek istiyorum.

Windows gezginine sağ tıkladığımda veya (ara sıra) belirli USB donanımını bağladığımda, ancak Java ile - hiç durduğumda duraklamalar gördüm.

GC hala kimseyle ilgili bir sorun mu?


Kabul ediyorum - GC duraklamalarını gördüğüm tek zaman, onları büyük ölçüde paralel çöp oluşturma koduyla kasten veya yanlışlıkla kışkırttığım
zamandı

28
Evet, GC büyük yığınlarla (> 16GB), özellikle de uzun süreli kullanımlı nesillerle uğraşmaya başladığınızda hala bir sorundur.
Simyacı

2
@ the-simyacı vay, yorumunuzu birkaç kez geçerken gördüm ve 16 GB dediniz bana çarptı !! Bunun çok büyük gecikmelere neden olabileceğinden kesinlikle emin olsam da, TÜM takasları devre dışı bıraktığınızı kontrol etmek istiyorum. Büyük bir bellek sisteminde, herhangi bir java değiş tokuşu kesinlikle sisteminizi öldürecektir (Çünkü, GC çok kolay takas değildir). Eminim bunu zaten yapmışsınızdır, ama sadece bahsetmek istedim - çünkü çok büyük bir fark yaratırdı. Hiç bu kadar ram içeren bir bilgisayar görmedim - ne kadar var? 32g?
Bill K

8
Evet, GC'ler, TP99.9 (ve üstü) limitlerini iyileştirmeyi ÇOK zor kılan şey olduklarından hizmetler için sorunludur. Özellikle "eski nesil" GC'ler, JVM'yi (ve hizmeti) birden çok saniyeliğine donduran ölüm tuzakları olabilir; ve isteklere genellikle tek basamaklı (veya düşük çift basamaklı) mili saniyede hizmet veren hizmetler için bu sorunludur. Buna değen şey, Amazon'un Simple Queue hizmeti tarafından kullanılan arka uç depolamayla ilgili pratik bir sorundu (AWS dahili olduğu için tonlarca ayrıntıya girilemez).
StaxMan

21
GC ile ilgili can sıkıcı şey, Azul'un yıllar önce, işlemcilerin bellek donanımını çok akıllıca kullanarak fark edilir bir duraklama süreleri olmadan yüzlerce gigabayt ile kolayca başa çıkabilen ustaca bir GC algoritması (Azul C4) icat etmiş olmasıdır. Ancak bunu kimse bilmiyor ve işletim sistemi tarafından biraz desteğe ihtiyaç duyduğu için büyük Java sürümlerinde yakında uygulanmayacak. Ve işletim sistemi satıcıları, insanlar algoritmayı öğrenene ve işletim sistemi satıcılarına baskı yapana kadar hiçbir şey yapmayacak. Bkz. Azulsystems.com/zing/pgc , managedruntime.org
Hans-Peter Störr

58

Ağır bir uygulamayla test ediyorum: 60-70 GB yığına ayrılmış, 20-50 GB herhangi bir zamanda kullanımda. Bu tür uygulamalarda, kilometrenizin değişebileceğini söylemek yetersiz kalıyor. Linux üzerinde JDK 1.6_22 çalıştırıyorum. Küçük sürümler önemlidir - yaklaşık 1.6_20'den önce, G1'de rastgele NullPointerExceptions'a neden olan hatalar vardı.

Çoğu zaman verdiğiniz duraklama hedefi içinde kalmanın çok iyi olduğunu buldum. Varsayılan, 100 ms'lik (0,1 saniye) bir duraklama gibi görünüyor ve ben de buna yarısını yapmasını söylüyorum (-XX: MaxGCPauseMillis = 50). Bununla birlikte, hafızası gerçekten azaldığında paniğe kapılır ve dünyayı durduracak bir çöp toplama işlemi yapar. 65 GB ile bu 30 saniye ile 2 dakika arasında sürer. (CPU sayısı muhtemelen bir fark yaratmaz; muhtemelen veri yolu hızıyla sınırlıdır.)

CMS ile karşılaştırıldığında (varsayılan sunucu GC değildir, ancak web sunucuları ve diğer gerçek zamanlı uygulamalar için olmalıdır), tipik duraklamalar çok daha öngörülebilirdir ve çok daha kısa yapılabilir. Şimdiye kadar CMS ile büyük duraklamalar için daha şanslıyım, ancak bu rastgele olabilir; 24 saatte bir sadece birkaç kez görüyorum. Şu anda üretim ortamımda hangisinin daha uygun olacağından emin değilim ama muhtemelen G1. Oracle bunu ayarlamaya devam ederse, eninde sonunda G1'in açık ara kazanan olacağından şüpheleniyorum.

Mevcut çöp toplayıcılarla ilgili bir sorununuz yoksa, şu anda G1'i düşünmeniz için bir neden yok. Bir GUI uygulaması gibi düşük gecikmeli bir uygulama çalıştırıyorsanız, MaxGCPauseMillis gerçekten düşük ayarlanmış olarak G1 muhtemelen doğru seçimdir. Toplu mod uygulaması çalıştırıyorsanız, G1 size hiçbir şey satın almaz.


14

Üretimde G1'i test etmemiş olsam da, GC'lerin "muazzam" yığınları olmayan durumlar için zaten sorunlu olduğunu yorumlayacağımı düşündüm. Spesifik olarak, örneğin 2 veya 4 konser içeren hizmetler, GC'den ciddi şekilde etkilenebilir. Genç nesil GC'ler genellikle tek basamaklı milisaniyelerde (veya en fazla çift basamaklı) bittikleri için sorunlu değildir. Ancak eski nesil koleksiyonlar, 1 gig veya üzeri eski nesil boyutlarda birkaç saniye sürdüğü için çok daha sorunludur.

Şimdi: teorik olarak CMS, operasyonlarının çoğunu aynı anda çalıştırabildiğinden, orada çok yardımcı olabilir. Ancak zamanla bunu yapamayacağı ve "dünyayı durdurmak" için geri çekilmesi gereken durumlar olacaktır. Ve bu olduğunda (diyelim ki 1 saat sonra - çok sık değil, ama yine de çok sık), lanet şapkalarınızı tutun. Bir dakika veya daha uzun sürebilir. Bu, özellikle maksimum gecikmeyi sınırlamaya çalışan hizmetler için sorunludur; diyelim ki 25 milisaniye yerine bir isteği yerine getirmek yerine on saniye veya daha fazla zaman alıyor. Müşterilere hakarete zarar vermek, daha sonra isteği zaman aşımına uğratır ve yeniden dener, bu da başka sorunlara yol açar (aka "bok fırtınası").

Bu, G1'in çok yardımcı olmasının umulduğu bir alandır. Depolama ve mesaj gönderimi için bulut hizmetleri sunan büyük bir şirkette çalıştım; ve CMS'yi kullanamadık çünkü çoğu zaman paralel çeşitlerden daha iyi çalışmasına rağmen bu erimelere sahipti. Yani yaklaşık bir saat boyunca işler güzeldi; ve sonra bir şeyler fana çarptı ... ve hizmet kümelere dayalı olduğu için, bir düğümün başı belaya girdiğinde, diğerleri genellikle onu takip etti (çünkü GC kaynaklı zaman aşımları, düğümün çöktüğüne inanarak düğümlerin yeniden yönlendirilmesine yol açtı).

GC'nin uygulamalar için bu kadar büyük bir sorun olduğunu düşünmüyorum ve belki de kümelenmemiş hizmetler bile daha az etkileniyor. Ancak, giderek daha fazla sistem kümeleniyor (özellikle NoSQL veri depoları sayesinde) ve yığın boyutları büyüyor. OldGen GC'ler, yığın boyutuyla süper doğrusal olarak ilişkilidir (yani, yığın boyutunu ikiye katlamanın GC süresini iki katına çıkarması, canlı veri kümesinin boyutunun da iki katına çıktığı varsayılır).


13

Azul CTO'su Gil Tene, Çöp Toplama ile ilgili sorunlara güzel bir genel bakışa ve Java Çöp Toplamayı Anlama ve Bununla İlgili Yapabilecekleriniz sunumunda çeşitli çözümlere ilişkin bir inceleme sunuyor ve bu makalede ek ayrıntılar var: http: // www.infoq.com/articles/azul_gc_in_detail .

Azul'un Zing JVM'mizdeki C4 Çöp Toplayıcısı hem paralel hem de eşzamanlıdır ve hem yeni hem de eski nesiller için aynı GC mekanizmasını kullanır, eşzamanlı olarak çalışır ve her iki durumda da sıkıştırır. En önemlisi, C4'ün dünyayı durduracak bir geri dönüşü yoktur. Tüm sıkıştırma, çalışan uygulama ile eşzamanlı olarak gerçekleştirilir. Çok büyük (yüzlerce GBayt) çalışan ve daha kötü durumda GC duraklatma süreleri <10 milisaniye ve uygulamaya bağlı olarak genellikle 1-2 milisaniyeden daha az olan müşterilerimiz var.

CMS ve G1 ile ilgili sorun, bir noktada Java yığın belleğinin sıkıştırılması gerektiğidir ve bu çöp toplayıcıların her ikisinin de sıkıştırmayı gerçekleştirmek için dünyayı / STW'yi durdurması (yani uygulamayı duraklatması). Dolayısıyla CMS ve G1, STW duraklamalarını zorlayabilirken, bunları ortadan kaldırmazlar. Ancak Azul'un C4'ü STW duraklamalarını tamamen ortadan kaldırıyor ve bu nedenle Zing'in devasa yığın boyutları için bile bu kadar düşük GC duraklamaları var.

Ve daha önceki bir cevapta verilen bir ifadeyi düzeltmek için Zing, İşletim Sisteminde herhangi bir değişiklik gerektirmez. Değiştirilmemiş Linux dağıtımlarında diğer JVM'ler gibi çalışır.


3
Merak ediyorum da Azul'un C4 söylediklerinizi nasıl başardı ve Sun ya da Oracle bunu başaramıyor. Büyük bir sır mı var yoksa bu sadece bir çeşit değiş tokuş mu?
George

5
Azul'un C4'ü, kökeni Azul'un donanım bilgi işlem araçlarına (kurumsal Java uygulamalarını çalıştırmak için tasarlanmış özel işlemcileri kullanan) sahip olan ve Linux çalıştıran normal x86 sunucularında çalışmak üzere geliştirilmiş çok benzersiz bir teknolojiye sahiptir. Diğer tüm kurumsal sınıf çöp toplayıcılar (ister Oracle'dan ister IBM'den) bir noktada dünyayı durdurma duraklamaları yapmak zorundadır - Azul C4'ün benzersiz özelliği, bu sorunlu STW duraklamalarını asla yapmamasıdır. Merak ediyorsanız, C4 koleksiyoncunun mucitleri nasıl çalıştığına dair bir makale yayınladılar: dl.acm.org/citation.cfm?id=1064988 .
Scott Sellers

Scott, burada blog.mikemccandless.com/2012/07/… 'nin Azul'un JVM kullanımı için belleği önceden ayıran bir çekirdek modülü gönderdiğini okudum . Bu doğru değil mi Doğruysa, çok fazla çekirdek değişikliği değil, yine de bir değişiklik.
Dan Pritts

4
George, iki kelime: patent korumalı. Dan, Zing'i satın aldığınızda, ödediğinizin bir kısmı, destekçilerinin uygulamanıza göre ayarlamasını sağlamaktır - ve buna genel sistem belleği kullanımı da dahildir. Çekirdek modülünün kendisi, çöp toplanan bir bellek bloğuna yazmayı engeller. Onu "duraklatmasız" yapan gizli sos budur: iş parçacıkları yalnızca bu bloklardan birine yazmaya çalışırlarsa dururlar ve sonra yalnızca bu bloğu sıkıştırmaya yetecek kadar uzun süre kalırlar.
David Leppik

13

Neredeyse iki yıldır G1GC'yi zaten kullanıyoruz. Görev açısından kritik işlem işleme sistemimizde harika çalışıyor ve yüksek verim, düşük duraklamalar, eşzamanlılık ve optimize edilmiş ağır bellek yönetimi için harika bir destek olduğunu kanıtladı.

Aşağıdaki JVM ayarlarını kullanıyoruz:

-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

Güncellenmiş

-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'de, -XX: + UseCompressedOops veya -XX: + DoEscapeAnalysis ayarlamanıza gerek yoktur, stand varsayılan olarak açıktır. Bakınız: docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
Mirko Ebert

8

G1 toplayıcı, tam koleksiyonların etkisini azaltır. Tam koleksiyon ihtiyacını zaten azalttığınız bir uygulamanız varsa, Concurrent map Sweep toplayıcı da aynı derecede iyidir ve benim deneyimime göre daha kısa küçük toplama sürelerine sahiptir.


"G1'in üretim kullanımına yalnızca bir Java destek sözleşmesi satın alındığında izin verildiğini unutmayın.", groups.google.com/forum/#!topic/javaposse/Vm0a4H-QY54 , yani bu bir efsane mi değil mi?
Christophe Roussy

1
@ChristopheRoussy Bunun artık doğru olup olmadığını bilmiyorum (veya gerçekten bunun doğru olduğuna dair kanıtım var) -XX: + UnlockCommercialFeatures gerektirmediğinden G1'in lisans gerektirmediğinden şüpheleniyorum.
Peter Lawrey


5

Yakın zamanda buradan taşındım

JDK 1.7.45'e sahip sunucularda 4G yığın ve 8 çekirdekli işlemcili CMS'den G1GC'ye .

(JDK 1.8.x G1GC, 1.7'ye tercih edilir, ancak bazı sınırlamalar nedeniyle 1.7.45 sürümüne bağlı kalmam gerekiyor)

Aşağıda temel parametreleri yapılandırdım ve diğer tüm parametreleri varsayılan değerlerde tuttum.

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

Bu parametrelere ince ayar yapmak istiyorsanız, bu oracle makalesine bir göz atın .

Temel gözlemler:

  1. Bellek kullanımı, CMS ile yüksek ve düşük değerlerin aksine G1GC ile tutarlıdır
  2. Maks. GC duraklatma süresi, CMS'ye kıyasla daha azdır
  3. Çöp toplamada harcanan zaman, CMS'ye kıyasla G1GC'de biraz yüksektir.
  4. CMS'ye kıyasla büyük koleksiyonların sayısı neredeyse yok denecek kadar azdır
  5. Küçük koleksiyonların sayısı CMS'ye kıyasla daha yüksek

Ama yine de Max GC duraklama süresinin CMS'den daha kısa olmasına sevindim. Maks GC duraklatma süresini 1,5 saniye olarak ayarladım ve bu değer henüz geçilmedi.

İlgili SE sorusu:

G1'de Java 7 (JDK 7) çöp toplama ve dokümantasyon


4

CMS, görevlendirilmiş nesneleri biriktirmeden çalıştırıyor olsanız bile performansın yavaşça düşmesine neden olabilir. Bunun nedeni, G1'in sözde önlediği bellek parçalanmasıdır.

Yalnızca ücretli destekle elde edilebilen G1 hakkındaki efsane tam da bu, bir efsanedir. Sun ve şimdi Oracle, bunu JDK sayfasında açıkladı.


4

G1 GC'nin daha iyi çalışması gerekiyor. Ancak -XX: MaxGCPauseMillis ayarı çok agresif ise, çöp çok yavaş toplanacaktır. İşte bu yüzden David Leppik'in örneğinde tam GC tetiklendi.


4

Terracotta Big Memory projemizde G1 Çöp Toplayıcı'yı yeni uyguladım. Farklı kollektör türleri üzerinde çalışırken G1, 600 ms'den daha kısa yanıt süresiyle bize en iyi sonuçları verdi.

Test sonuçlarını (toplamda 26) burada bulabilirsiniz

Umarım yardımcı olur.


3

Kısa süre önce Twicsy'nin bir kısmını 128GB RAM'li yeni bir sunucuya taşıdım ve 1.7 kullanmaya karar verdim. 1.6 ile kullandığım tüm aynı bellek ayarlarını kullanmaya başladım (500 MB'den 15 GB'a kadar her yerde çeşitli şeyler yapan birkaç örneğim var ve şimdi 40 GB'lık yeni bir tane var) ve bu hiç de iyi sonuç vermedi . 1.7, 1.6'dan daha fazla yığın kullanıyor gibi görünüyor ve ilk birkaç gün içinde birçok sorunla karşılaştım. Neyse ki çalışacak bol miktarda RAM'im vardı ve süreçlerimin çoğu için RAM'i yükselttim, ancak yine de bazı sorunlar yaşıyordum. Benim normal MO'm, birkaç gigabaytlık bir maksimum yığınla bile çok küçük bir minimum yığın boyutu olan 16m kullanmak ve ardından artımlı GC'yi açmaktı. Bu, duraklamaları minimumda tuttu. Yine de bu işe yaramıyor ve minimum boyutu yığın içinde ortalama olarak kullanmamı beklediğim şeye yükseltmem gerekiyordu. ve bu çok iyi sonuçlandı. Hala artımlı GC açık, ancak olmadan deneyeceğim. Artık hiçbir duraklama yok ve işler çok hızlı ilerliyor gibi görünüyor. Bu yüzden, hikayenin ahlaki olarak hafıza ayarlarınızın 1.6'dan 1.7'ye mükemmel bir şekilde çevrilmesini beklemediğini düşünüyorum.


2

G1, uygulamayı çok daha çevik hale getirir: uygulamanın gecikmesi artar - uygulama "yumuşak gerçek zamanlı" olarak adlandırılabilir. Bu, iki tür GC çalıştırmasının (küçük küçük olanlar ve Tenured Gen'de bir büyük) eşit boyutlu küçük olanlarla değiştirilmesiyle yapılır.

Daha fazla ayrıntı için şuna bakın: http://geekroom.de/java/java-expertise-g1-fur-java-7/


1

Küçük ve büyük Yığın için Java ile çalışıyorum ve kısıtlamalar diğerlerinden daha katı olabileceğinden, GC ve Tam GC sorusu her gün ortaya çıkıyor: belirli bir ortamda, 0.1 saniye çöpçü GC veya Tam GC, öldür basitçe fonctionnalité ve ince taneli konfigürasyona sahip olmak ve yetenek önemlidir (CMS, iCMS, diğerleri ... hedef, neredeyse gerçek zamanlı tedavi ile mümkün olan en iyi yanıt süresine sahip olmaktır (burada gerçek zamanlı tedavi genellikle 25 ms'dir) , bu nedenle, temel olarak, GC ergonomisi ve heuristique'deki herhangi bir iyileştirmeye açığız!


1

Java 8'de ve ayrıca Groovy'de (ayrıca Java 8) G1GC kullanıyorum ve çeşitli iş yükleri yapıyorum ve genel olarak G1GC şu şekilde çalışıyor:

  • Bellek kullanımı çok düşüktür, örneğin varsayılan Java ayarlarına kıyasla 500MB yerine 100MB

  • Yanıt süresi tutarlı ve çok düşük

  • Varsayılan ayarlar ile G1GC arasındaki performans, en kötü senaryoda G1GC kullanılırken (ayar yapılmadan, tek iş parçacıklı uygulama)% 20 yavaşlamadır. İyi yanıt süresi ve düşük bellek kullanımı pek düşünülmüyor.

  • Çok iş parçacıklı Tomcat'ten çalıştırıldığında, genel performans% 30 daha iyidir ve bellek kullanımı çok daha düşüktür ve yanıt süreleri çok daha düşüktür.

Yani genel olarak, gerçekten çeşitli iş yükleri kullanırken, G1GC çok iş parçacıklı uygulamalar için Java 8 için çok iyi bir toplayıcıdır ve tek iş parçacıklı uygulamalar için bile bazı faydalar vardır.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.