Java GC ayarı nasıl yapılır?

Yazar | Yang Xiaofeng

Kaynak | Geek Time "Java Core Technologies üzerine 36 Ders" sütunu

Dış kaynaklardan G1 girişinin çoğunun hala JDK 7 veya daha önceki sürümlerin uygulanmasında olduğunu ve birçok sonucun büyük sapmalara sahip olduğunu ve hatta bazı geçmiş GC seçeneklerinin artık önerilmediğini buldum. Bu nedenle, bugün ayrıntılı açıklama için JDK'nın yeni sürümünde varsayılan G1 GC'yi seçeceğim ve tipik senaryoları ve ayarlama fikirlerini ayarlama pratiği perspektifinden analiz edeceğim. Bu bilgiyi birlikte güncelleyelim.

Bugün size sormak istediğim soru şu: GC ayarlama fikirleriniz hakkında konuşun mu?

Tipik cevap

Ayarlama söz konusu olduğunda, bu belirli bir senaryo ve belirli bir amaç için olmalıdır.GC ayarlaması için, her şeyden önce, ayarlama hedefleri konusunda net olmanız gerekir? Performans açısından bakıldığında, genellikle üç husus söz konusudur: bellek ayak izi, gecikme ve aktarım hızı. Çoğu durumda, ayarlama hedeflerden birine veya ikisine odaklanır ve nadiren Üç farklı açının düşünülebileceği durumlar vardır. Tabii ki, yukarıdaki olağan üç özelliğe ek olarak, diğer GC ile ilgili senaryoların da dikkate alınması gerekebilir.Örneğin, OOM mantıksız GC ile ilgili parametrelerle de ilgili olabilir veya uygulama başlatma hızı gereksinimleri için GC de dikkate alınacaktır. .

Temel ayarlama fikirleri şu şekilde özetlenebilir:

  • Uygulama gereksinimlerini ve sorunlarını anlayın ve ayarlama hedeflerini belirleyin. Diyelim ki bir uygulama hizmeti geliştirdik, ancak ara sıra performans kesintileri ve uzun hizmet duraklamaları bulduk. Kullanıcının kabul edilebilir yanıt süresini ve iş hacmini değerlendirin ve GC duraklamasının mümkün olduğunca 200 ms içinde kontrol edilmesi ve belirli bir standart verimin garanti edilmesi umuduyla hedefi basitleştirin.
  • JVM ve GC'nin durumunu kavrayın, belirli sorunları bulun ve GC ayarının gerçekten gerekli olduğundan emin olun. Birçok spesifik yöntem vardır: Örneğin, GC'yi ve diğer ilgili durumu görüntülemek için jstat gibi araçları kullanabilir, GC günlüğünü açabilir veya işletim sistemi tarafından sağlanan tanılama araçlarını kullanabilirsiniz. Örneğin, GC günlüğünü izleyerek, GC'nin belirli bir zamanda uzun bir duraklamaya sahip olup olmadığını öğrenebilirsiniz, bu da uygulamanın zamansız yanıt vermesine neden olur.
  • Burada, seçilen GC türünün uygulamamızın özelliklerini karşılayıp karşılamadığını düşünmemiz gerekir. Eğer öyleyse, spesifik sorun nerede ise, Küçük GC çok uzun mu yoksa Karışık GC vb. Anormal duraklamalar; değilse, CMS gibi hangi türe geçileceğini düşünün. Ve G1, düşük gecikmeye daha fazla odaklanan GC seçenekleridir.
  • Analiz yoluyla özel ayarlanmış parametreleri veya yazılım ve donanım konfigürasyonunu belirleyin.
  • Ayarlama hedefine ulaşılıp ulaşılmadığını doğrulayın. Hedefe ulaşılırsa, ayarlamayı bitirmeyi düşünün; aksi takdirde analiz, ayarlama ve doğrulama sürecini tekrarlayın.

Test sitesi analizi

Bugün incelenen GC ayarlama problemi, JVM ayarlamasının temel bir yönüdür. Birçok JVM ayarlama gereksinimi, sonunda GC ayarlamasına uygulanacak veya onunla ilgili olacaktır. Sağladığım şey ortak bir fikir.

Belirli sorunları hızlı bir şekilde bulmak ve çözmek için, JVM ve GC bilgilerinin yanı sıra gerçek ayarlama deneyiminin özetinde ve hatta bazen birikmiş deneyimin sezgisel yargısından ustalaşmak hala gereklidir. Görüşmeci, projede karşılaşılan gerçek sorunları sormaya devam edebilir.Eğer bağlamı açık ve kısaca tanıtabilir ve ardından teşhis fikirlerini ve ayarlama uygulama sürecini ifade edebilirseniz, bu iyi bir artı olacaktır.

Sütun, belirli bir proje deneyimi sağlayamasa da, ortak ayar fikirleri ve yöntemlerinde ustalaşmanıza yardımcı olabilir; bu, ister bir röportaj olsun ister gerçek bir çalışma olsun çok faydalıdır. Ek olarak, aşağıdaki farklı bakış açılarından ekleyeceğim:

  • Belirli GC türleri söz konusu olduğunda, JVM'nin gerçek performansı daha karmaşıktır. Şu anda, G1, JDK'nın yeni sürümü için varsayılan seçenek haline geldi, bu nedenle derinlemesine anlayışınıza değer.
  • G1 GC hızlı bir şekilde geliştirildiğinden, gelişimine ve değişikliklerine, özellikle davranış ve konfigürasyondaki değişikliklere odaklanacağım. Ayrıca, JVM'nin hızlı gelişimi nedeniyle, GC günlüklerinin toplanması ve diğer yönler de büyük ölçüde iyileştirildi. Bu nedenle, son derste size bıraktığım soru log ile ilgili seçenekler hakkındadır. Açıklamayı okuduktan sonra, inanıyorum ki, Çok şaşkın.
  • GC ayarlama uygulaması perspektifinden, ortak sorunlar için ayarlama fikirlerini ve yöntemlerini anlayın.

Bilgi genişlemesi

Öncelikle G1 GC'nin iç yapısını ve ana mekanizmasını anlayalım.

Hafıza alanı açısından G1 de yaş kavramına sahiptir, ancak daha önce tanıttığım hafıza yapısından çok farklıdır.İç kısmı satranç tahtasına benzer bölgelerden oluşur.Lütfen aşağıdaki diyagrama bakınız.

Bölgenin boyutu aynı. Değer, 1M ile 32M bayt arasında 2'nin kuvvetidir. JVM, aynı boyuttaki yaklaşık 2048 bölgeyi bölmeye çalışacaktır. Bu, heapRegionBounds.hpp kaynak kodundan görülebilir. Elbette bu sayı manuel olarak ayarlanabilir ve G1 de yığın boyutuna göre otomatik olarak ayarlanacaktır.

G1 uygulamasında yaş, bölgenin o kısmında somutlaşan mantıksal bir kavramdır ve diğer kısmı Survivor olarak kullanılır.Beklenen Eski bölge dışında, G1 bölge boyutunun% 50'sini aşan nesnelere sahip olacaktır (uygulamalarda, genellikle bayt Veya karakter dizisi) Humongous nesneler olarak sınıflandırılır ve ilgili bölgelere yerleştirilir. Mantıksal olarak, Humongous bölgesi eski neslin bir parçasıdır, çünkü bu kadar büyük nesneleri kopyalamak çok pahalı bir işlemdir ve yeni nesil GC kopyalama algoritması için uygun değildir.

Bölge tasarımının yan etkilerini düşünebilir misiniz?

Örneğin, aynı bölge boyutunu ve büyük nesneyi garanti etmek zordur, bu da alan israfına neden olur. Diyagramımdaki bazı alanların Humongous renklerde olduğunu fark ettiniz mi bilmiyorum, ancak bunlar adlarla işaretlenmemiş. Bu, çok büyük nesnelerin birden fazla bölgeyi işgal edebileceğini belirtmek içindir. Dahası, bölge çok küçük ve uygunsuz, büyük nesneler tahsis ederken bitişik alan bulmayı zorlaştıracak Bu uzun süredir devam eden bir durum.Lütfen OpenJDK topluluğundaki tartışmaya bakın. Bu, özünde bir JVM hatası olarak da kabul edilebilir, ancak çözüm de çok basit olmasına rağmen, doğrudan daha büyük bir bölge boyutu ayarlayın, parametreler aşağıdaki gibidir:

-XX: G1HeapRegionSize = < N, örneğin 16 > M

GC algoritması perspektifinden bakıldığında, G1, aşağıdaki gibi basitleştirilebilen ve anlaşılabilen bir bileşik algoritma seçer:

  • Yeni nesilde, G1 hala paralel bir çoğaltma algoritması kullanıyor, bu nedenle Stop-The-World duraklamaları da gerçekleşecek.
  • Yaşlılıkta, vakaların çoğu eşzamanlı işaretlemedir ve sıkıştırma yeni nesil GC ile bir bindirmede gerçekleştirilir ve bu genel bir düzenleme değil, artan bir süreçtir.

Geleneksel olarak, insanlar genç GC (Young GC) Minor GC'yi ve eski GC'yi genel Tam GC'den farklı olan Major GC olarak adlandırmayı severler. Ancak modern GC'de bu kavram artık doğru değil. G1 için:

  • Küçük GC hala mevcuttur, ancak belirli süreç farklı olacaktır ve Hatırlanan Küme gibi ilgili işlemler dahil edilecektir.
  • Yaşlılıkta geri dönüşüm, Karışık GC'ye dayanır. Eşzamanlı işaret bittikten sonra, JVM, çöp toplama için yeterli bilgiye sahiptir.Karışık GC, sadece Eden ve Survivor alanlarını aynı anda temizlemekle kalmaz, aynı zamanda Eski alanın bir bölümünü de temizler. Aşağıdaki parametreleri ayarlayarak tetikleme eşiğini belirtebilir ve en fazla bir Karışık GC'ye dahil edilen bölgenin oranını ayarlayabilirsiniz.
--XX: G1MixedGCLiveThresholdPercent XX: G1OldCSetRegionThresholdPercent

G1'in dahili çalışması perspektifinden, aşağıdaki diyagram, normal çalışma sırasında G1'in durum akış değişikliklerini açıklamaktadır.Elbette, bir kaçış arızası durumunda, Tam GC tetiklenecektir.

G1'de birbiriyle ilişkili birçok kavram vardır. Bir anahtar nokta, nesnelerin bölgeler arasındaki referans ilişkisini kaydetmek ve sürdürmek için kullanılan Hatırlanan Küme'dir. Bunu neden yapmanız gerekiyor? Yeni nesil GC'nin bir kopya algoritması olduğunu, yani benzer nesnelerin Eden veya Survivor'dan alana "hareketinin" aslında "kopya" olduğunu ve aslında yeni bir nesne olduğunu hayal edin. Bu süreçte eski nesilden yeni nesile kadar bölgeler arası referansların hala geçerli olduğundan emin olmak gerekiyor. Aşağıdaki diyagram, ilgili tasarımı göstermektedir.

G1'in ek yükünün çoğu Hatırlanan Kümeden gelir.Örneğin, genellikle Yığın boyutunun yaklaşık% 20'sini veya daha fazlasını kaplar ki bu çok önemli bir orandır. Ayrıca, nesneleri kopyalarken, Kart Tablosu bilgilerini taramamız ve değiştirmemiz gerektiğinden, bu hız kopyalama hızını etkiler ve bu da duraklama süresini etkiler.

G1'in iç kısımlarını açıklayan birçok materyal var, bu yüzden onları tekrar etmeyeceğim. Dahili yapı ve algoritmalar hakkında daha fazla bilgi edinmek istiyorsanız, bazı özel girişlere bakmanızı öneririm. Kitaplar için, Charlie Hunt ve diğerleri tarafından yazılan "Java Performance Companion" ı öneririm.

Daha sonra, farkında olmayabileceğiniz G1 davranış değişikliklerini tanıtacağım.Bir dereceye kadar, kolondaki diğer derslerde bahsedilen zamansız tip kaldırma problemi gibi bazı problemleri çözecekler.

  • Yukarıda bahsedilen Humongous nesnelerin tahsisi ve geri dönüşümü, birçok hafıza sorununun kaynağıdır.Eski neslin bir parçası olarak, Humongous bölgesi genellikle eşzamanlı işaretlemenin sona ermesinden sonra geri dönüştürülmüş olarak kabul edilir.Ancak, G1'in yeni sürümünde, Humongous nesne geri dönüşümü alır Daha radikal bir strateji.
  • G1'in eski nesil bölgeler arasındaki nesne referanslarını kaydettiğini ve Humongous nesnelerin sayısının sınırlı olduğunu biliyoruz, bu nedenle eski nesilde buna referans veren nesneler olup olmadığını hızlı bir şekilde anlayabiliriz. Değilse, geri dönüştürülmesini engellemenin tek yolu, yeni nesilde kendisine atıfta bulunan bir nesne olup olmadığıdır, ancak bu bilgi Young GC'de bilinebilir, bu nedenle Humongous nesneleri Young GC'de geri dönüştürmek tamamen mümkündür. Diğer eski nesil nesneler gibi, eşzamanlı işaretin sonunu bekleyin.
  • 8u20'den sonra, dize tekrarının karakteri, çöp toplama işleminde, G1 yeni oluşturulan dize nesnesini kuyruğa ve ardından Young GC'den sonra eşzamanlı olarak (STW değil) dahili verileri (char dizisi, JDK 9 bayt dizisi olduktan sonra), tutarlı dizge sıralanır, yani aynı diziye başvurulur. Aşağıdaki parametrelerle etkinleştirebilirsiniz:
-XX: + UseStringDeduplication

Bu tür bir ağırlık, çok fazla bellek alanı tasarrufu sağlasa da, bu eşzamanlı işlemin bazı CPU kaynaklarını kullanacağını ve ayrıca Young GC'nin biraz yavaşlamasına neden olacağını unutmayın.

  • Tür boşaltma, bazı Java uygulamalarını uzun süredir rahatsız eden bir sorundur.Sütunun 25. dersinde, bir sınıfın ancak yüklenen özel sınıf yükleyici geri dönüştürüldükten sonra kaldırılabileceğini anlattım. Kalıcı nesil değiştirildikten sonra meta veri alanı iyileştirildi, ancak yine de sorunlar olabilir.

G1 tipi kaldırmada herhangi bir gelişme var mı? G1'in yalnızca Full GC oluştuğunda tip boşaltma yaptığı birçok malzemede belirtilmiştir, ancak bu açıkça istediğimiz şey değildir. Kaldırma türünü görüntülemek için aşağıdaki parametreleri ekleyebilirsiniz:

-XX: + TraceClassUnloading

Neyse ki modern G1'de durum böyle değil. 8u40'tan sonra, G1 varsayılan olarak aşağıdaki seçenekleri ekledi:

-XX: + ClassUnloadingWithConcurrentMark

Diğer bir deyişle, eşzamanlı işaretleme aşaması sona erdikten sonra, JVM tip boşaltma gerçekleştirir.

  • Yaşlılıkta nesne koleksiyonunun temelde eşzamanlı işaretlemenin sonunu beklemesi gerektiğini biliyoruz. Bu, eşzamanlı işaretlemenin zamanında tamamlanmaması, yığının dolmasına neden olması, ancak eski alan geri kazanılmaması durumunda Tam GC'nin tetikleneceği, dolayısıyla eşzamanlı işaretlemeyi tetikleme zamanının çok önemli olduğu anlamına gelir. Erken G1 ayarında, aşağıdaki parametreler genellikle ayarlanır, ancak evrensel bir değer vermek zordur ve genellikle gerçek işletim sonuçlarına göre ayarlanır.
-XX: InitiatingHeapOccupancyPercent

JDK 9'dan sonra G1'in uygulanmasında, bu ayarlama gereksinimi çok daha az olacaktır, çünkü JVM bu parametreyi yalnızca başlangıç değeri olarak kullanacak, çalışma zamanında örnekleyecek, istatistiksel veriler elde edecek ve ardından eşzamanlı işaretleme başlangıç zamanını buna göre dinamik olarak ayarlayacaktır. Karşılık gelen JVM parametreleri aşağıdaki gibidir ve varsayılan olarak etkinleştirilmiştir:

-XX: + G1UseAdaptiveIHOP
  • Mevcut verilerde çoğu, G1'in Full GC'sinin en kötü tek iş parçacıklı seri GC olduğuna işaret ediyor. Aslında, en son JDK'yı kullanırsanız, Full GC'nin de paralel olarak gerçekleştirildiğini ve genel senaryolarda Parallel GC'nin Full GC uygulamasından daha iyi performans gösterdiğini göreceksiniz.

Elbette, burada tanıtılmayacak daha hızlı Kart Tablosu taraması vb. Gibi birçok başka değişiklik vardır, çünkü bunlar davranışta değişiklik getirmezler ve temelde ayar seçeneklerini etkilemezler.

G1'in dahili mekanizması yukarıda tanıtıldı ve bazı ayar önerileri serpiştirildi.İşte bir bütün olarak bazı ayar önerileri. Her şeyden önce, mümkün olduğunca daha yeni bir JDK sürümüne yükseltmeniz tavsiye edilir.Yukarıda sunulan iyileştirmelerden, insanların sık sık tartıştığı birçok sorunun aslında JDK yükseltilerek çözülebileceğini görebiliriz.

İkinci olarak, GC ayarlama bilgilerini toplama yönteminde ustalaşın. Mümkün olduğunca kapsamlı, ayrıntılı ve doğru bilgilere hakim olmak, yalnızca GC ayarının değil, çeşitli ayarların temelidir. Gelin GC günlüğünü açmaya bir göz atalım.Bu çok basit bir mesele gibi görünüyor, ancak gerçekten ustalaştığınıza emin misiniz?

Yaygın olarak kullanılan iki seçeneğe ek olarak,

-XX: + PrintGCDayrıntıları -XX: + PrintGCDateStamps

Ayrıca çok kullanışlı bazı günlük seçenekleri vardır ve birçok özel sorunun teşhisi şu seçeneklere bağlıdır:

-XX: + PrintAdaptiveSizePolicy // G1 Ergonomi ile ilgili bilgileri yazdırın

GC içindeki bazı davranışların uyarlamalı olarak tetiklendiğini biliyoruz PrintAdaptiveSizePolicy kullanarak, JVM'nin neden olmasını istemeyebileceğimiz bazı eylemler yaptığını öğrenebiliriz. Örneğin, G1 ayarı için temel bir öneri, çok sayıda Humongous nesne tahsisinden kaçınmaktır.Ergonomi bilgileri bunun gerçekleştiğini gösteriyorsa, yığın boyutunu artırmayı veya doğrudan bölge boyutunu artırmayı düşünebilirsiniz.

Alıntıların zamanında temizlenmediğinden şüpheleniyorsanız, birikimin nerede olduğunu öğrenmek için aşağıdaki seçenekleri açabilirsiniz.

-XX: + PrintReferenceGC

Ek olarak, paralel referans işleme seçeneklerinin altındaki seçenekleri açmanız önerilir.

-XX: + ParallelRefProcEnabled

Dikkat edilmesi gereken bir nokta, JDK 9'daki JVM ve GC günlüğe kaydetme mekanizmasının yeniden düzenlenmiş olmasıdır. Aslında, daha önce bahsettiğim

PrintGCDetails eski olarak işaretlendi ve PrintGCDateStamps kaldırıldı ve JVM'nin başlatılamamasına neden olacağı belirtildi. Yeni konfigürasyon parametrelerini sorgulamak için aşağıdaki komutu kullanabilirsiniz.

java -Xlog: yardım

Son olarak, bazı genel uygulamalara bakın ve daha önce tanıttığım iç yapıyı ve mekanizmayı anlayın, birçok sonuç bir bakışta anlaşılır, örneğin:

  • Young GC'nin çok zaman alıcı olduğu tespit edilirse, bunun nedeni muhtemelen Senozoik'in çok büyük olmasıdır.Senozoik'in minimum oranını azaltmayı düşünebiliriz.
-XX: G1NewSizePercent

Maksimum değerin düşürülmesi, Young GC gecikmesinin azaltılmasına da yardımcı olur.

-XX: G1MaxNewSizePercent

Doğrudan G1 için küçük bir gecikme hedefi değeri belirlersek, yeni nesli azaltma etkisine sahip olacak, ancak verimi etkileyecektir.

  • Karışık GC uzun bir gecikmeye sahipse ne yapmalıyız?

Daha önce söylediğimi hatırlayın, eski bölgenin bir kısmı Karışık GC'ye dahil edilecek, bir seferde işlenen bölge sayısını azaltmak doğrudan seçimlerden biridir.

Maksimum değerini kontrol etmek için yukarıda G1OldCSetRegionThresholdPercent'i tanıttım. Karışık GC'lerin sayısını artırmak için aşağıdaki parametreleri de kullanabilirsiniz. Mevcut varsayılan değer 8'dir. Karışık GC'lerin sayısındaki artış, dahil edilen bölgenin her seferinde azaldığı anlamına gelir.

-XX: G1MixedGCCountTarget

Aşırı ayarlamadan kaçınmak için, G1'in büyük yığınlara karşı çok dostça olduğu ve çalışma mekanizmasının da belirli bir alan israf etmesi gerektiğine dikkat edilmelidir.Bazen yığına biraz daha fazla alan vermek, sert ayar yapmaktan daha pratiktir.

Bugün temel GC ayarlama fikirlerini sıraladım ve G1'in iç yapısını ve en son davranış değişikliklerini ayrıntılı olarak açıkladım. Genel olarak, G1'in ayarlanması nispeten basit ve sezgiseldir, çünkü duraklama süresini ve diğer hedefleri doğrudan belirleyebilir ve içerisine çeşitli akıllı uyarlanabilir mekanizmalar ekleyebilirsiniz.Umarım tüm bu çabalar, günlük uygulamaları geliştirmenize yardımcı olur. Zaman daha verimli.

ELECOM Double Eleven başlar, değerli ürünler nelerdir
önceki
190329 Cep telefonu haberleri Lu Han'ın ciddi ve titiz çevrimiçi iletim sahnesini eksi on
Sonraki
Eminem baharatlı tavukla mı çıkıyor? ! Baharatlı tavuk, sosyal ağ sitelerinde onaylandı!
Google'ın video sitesi Youtube, kısa süre önce çok sert bir gençlik draması başlattı
Hip-hop kültürünün dört unsurundan biri (Hip-hop)
Pratikten "Kore Hip Hop" un şampiyonu nasıl oldu?
İzledikten sonra beni çocuksu yapan gerçek hayattaki fantastik filmler
2018'in en iyi on Avrupa filmi seçimimi tavsiye et
Kong Ming, Dongfeng'i ödünç aldı, Dongfeng Motor nerede?
Kollarınızı sıvayın ve "iyi talihi" toplamak için çok çalışın
Gerçek "Kore'de Hip Hop" "Bana Parayı Göster" ne tür bir gösteri
"Transformers 4" oyuncusu Mark Wahlberg'in diğer yüksek puanlı film önerileri
Değerlendirme Günlüğü: iPhone XS Max ile ilgili 11 günlük araştırmam
K-pop-Quan Zhilong'un tartışmasız kralı
To Top