Java'nın C / C ++ ile karşılaştırıldığında en önemli özelliği, C / C ++ 'nın en zahmetli bellek yönetimi sorununu çözen ve programcıların programa odaklanmasına olanak tanıyan otomatik çöp toplamanın (bundan sonra GC otomatik çöp toplamaya atıfta bulunmak için kullanılacaktır) tanıtılmasıdır. Kendi başına bellek geri dönüşümü konusunda endişelenmenize gerek yok, bu Java'nın bu kadar popüler olmasının önemli nedenlerinden biridir. GC gerçekten programcıların üretkenliğini serbest bırakır, ancak programcıların varlığını algılaması zordur. Yemekten sonra tabakları masanın üzerine koyun ve çıkın, garson bu tabakları sizin için toplasın, garsonun ne zaman alacağı, nasıl alacağı umurunuzda değil.
Bazı insanlar, GC temizliği otomatik olarak tamamladığından, GC'yi anlamamakta yanlış bir şey olmadığını söylüyor. Çoğu durumda sorun yoktur, ancak bazı performans ayarı, sorun giderme vb. İçeriyorsa, GC'nin derinlemesine anlaşılması hala gereklidir.Meituan, hizmet yanıt süresini TP90 ve TP99'u azaltmak için JVM ile ilgili GC parametrelerini ayarladıktan sonra. 10ms + sonrasında, hizmet kullanılabilirliği büyük ölçüde iyileştirildi! Bu nedenle, derinlemesine bir GC anlayışı, iyi bir Java programcısı olmak için gerekli bir derstir!
Bu makale çöp toplamayı aşağıdaki yönlerden açıklayacaktır.
Çok sayıda metin var, ancak okuyucuların anlamasını kolaylaştırmak için pek çok GC animasyonu ekleniyor. İzledikten sonra çok fazla kazanç olacağına inanıyorum
JVM bellek alanı
Çöp toplama mekanizmasını anlamak için önce çöp toplamanın esas olarak hangi verileri topladığını ve verilerin esas olarak hangi alanda olduğunu bilmemiz gerekir, bu nedenle JVM'nin bellek alanına birlikte bakalım
Bu numaraları kaydetmenin ne faydası var? Java sanal makinesinin çoklu okuma işleminin sırayla iş parçacıkları arasında geçiş yaparak ve işlemci zamanı tahsis ederek gerçekleştirildiğini biliyoruz. Herhangi bir zamanda, bir işlemci yalnızca bir iş parçacığı yürütecektir. Bu iş parçacığının ayrılan zaman dilimi yürütüldüğünde (iş parçacığı askıya alındı), işlemci yürütmek için başka bir iş parçacığına geçecektir.Parlak olan iş parçacığının bir sonraki çalıştırılışında (iş parçacığını uyandırmak), en son nerede olduğunu nasıl anlarsınız? Program sayacına kaydedilen satır numarası göstergesinden bilinebilir, bu nedenle program sayacının ana işlevi, iş parçacığının çalışma durumunu kaydetmektir, böylece iş parçacığı uyandırıldığında, en son askıya alındığı durumdan çalışmaya devam edebilir. Program sayacının, Java sanal makine spesifikasyonunda herhangi bir OOM koşulu belirtmeyen tek alan olduğunu ve bu nedenle bu alanın GC gerektirmediğini unutmayın.
Seslendirme: Bir problem hakkında düşündüğünüzde, yığın dışı bellek GC tarafından kontrol edilmez ve GC aracılığıyla serbest bırakılamaz. O zaman hangi biçimde serbest bırakılmalı? Onu sadece yaratamaz ve bırakamazsınız.Bu durumda, hafıza yakında dolabilir. Ayrıntılı bir açıklama için lütfen makalenin sonundaki referans makalesine bakın.
Yığın: İlk birkaç veri alanı GC değildir, bu nedenle sadece yığın kalır Evet, bu GC'nin oluştuğu alandır! Nesne örnekleri ve dizileri öbek üzerinde tahsis edilir ve GC de esas olarak bu iki tür veriyi geri dönüştürür.Bu aynı zamanda daha sonra analiz etmemiz gereken alandır.
Çöp nasıl belirlenir
Önceki bölümde, JVM'nin bellek alanını ayrıntılı olarak tanımladık.GC'nin esas olarak yığın içinde oluştuğunu bilerek, GC, nesne örneğinin veya yığındaki verilerin çöp olup olmadığını nasıl belirler veya belirli verilerin çöp olup olmadığını belirlemek için hangi yöntemler vardır? .
Referans sayma
Düşünmenin en kolay yolu referans sayma yöntemidir.Referans sayma yöntemi olarak adlandırılır. Basitçe ifade etmek gerekirse, nesneye bir kez referans verilir ve referansların sayısı nesne başlığına eklenir. Referans verilmiyorsa (referans sayısı 0'dır), Daha sonra bu nesne geri dönüştürülebilir
String ref = new String ("Java");Yukarıdaki ref1 kodu sağda tanımlanan nesneye atıfta bulunur, dolayısıyla referans sayısı 1'dir
Yukarıdaki koddan sonra bir ref = null eklerseniz, nesneye başvurulmadığından, referans sayısı 0 olarak ayarlanır ve herhangi bir değişken tarafından başvurulmadığından bu sefer geri dönüştürülür. Animasyon aşağıdaki gibidir.
Görünüşe göre referans sayma ile ilgili bir sorun yok, ancak büyük bir sorunu çözemez: döngüsel referanslar! Döngüsel referans nedir
public class TestRC { TestRC örneği; public TestRC (Dize adı) { } public static void main (String args) { // ilk adım A a = new TestRC ("a"); B b = yeni TestRC ("b"); // ikinci adım a.instance = b; b.instance = a; // üçüncü adım a = boş; b = boş; } }Adım adım bir resim çizin
Üçüncü adımda, hem a hem de b null olarak ayarlansa da, işaret ettikleri nesneler birbirlerini gösterdikleri için (referans sayısı 1'dir), geri dönüştürülemezler, çünkü tam olarak dairesel referans problemi çözülemez. Bu nedenle, modern sanal makineler, bir nesnenin geri dönüştürülmesi gerekip gerekmediğini belirlemek için referans sayımı kullanmaz.
Erişilebilirlik algoritması
Modern sanal makineler temelde bir nesnenin canlı olup olmadığını belirlemek için bu algoritmayı kullanır.Erişilebilirlik algoritmasının prensibi, GC Kökü adı verilen bir dizi nesneden başlar, işaret ettikleri bir sonraki düğüme ve ardından başlangıç noktası olarak sonraki düğüme götürür. Bu düğüm tarafından gösterilen sonraki düğüme gidin. . . (Bu şekilde, GC Kökü tarafından dizilen bir satıra referans zinciri denir), tüm düğümler geçilene kadar, ilgili nesneler GC Kökünden başlayan herhangi bir referans zincirinde değilse, bu nesneler "çöp" olarak değerlendirilecektir. ", GC tarafından geri dönüştürülecektir.
Şekilde gösterildiği gibi, erişilebilirlik algoritması yukarıdaki dairesel referans problemini çözmek için kullanılıyorsa, a, b'ye GC Kökünden ulaşılamadığından, a, b geri dönüştürülebilir
a, b Nesne geri dönüştürülebilir ise, geri kazanılacak mı? Hayır, nesnenin finalize yöntemi nesneye mücadele etme şansı verir. Nesne erişilemez olduğunda (geri dönüştürülebilir), bir GC oluştuğunda, önce nesnenin olup olmadığını belirleyecektir. Finalize yöntemi çalıştırılır.İşlem yapılmazsa, önce finalize yöntemi çalıştırılır.Bu yöntemde mevcut nesneyi GC Roots ile ilişkilendirebiliriz, böylece finalize yöntemini çalıştırdıktan sonra, GC nesnenin tekrar ulaşılabilir olup olmadığına karar verir. Erişilebilir değilse, o zaman Ulaşılabilirse geri dönüştürülecek, geri dönüştürülmeyecek!
Not: Sonlandırma yöntemi yalnızca bir kez yürütülecektir.Nesne, sonlandırma yöntemi ilk çalıştırıldığında erişilebilir hale gelirse, geri dönüştürülmez, ancak nesne yeniden GC ise, sonlandırma yöntemi göz ardı edilir ve nesne geri dönüştürülür! Hatırla bunu!
Peki bu GC Kökleri tam olarak nedir ve hangi nesneler GC Kökleri olarak kullanılabilir? Aşağıdaki kategoriler vardır
Sanal makine yığınında başvurulan nesneler
Aşağıdaki kodda gösterildiği gibi, a, yığın çerçevesindeki yerel bir değişkendir. A = null olduğunda, a şu anda bir GC Kökü gibi davrandığından, a, new Test () 'in işaret ettiği orijinal örnekten ayrılır, böylece nesne Geri dönüşüm.
public class Test { public static void main (String args) { Test a = yeni Test (); a = boş; } }Yöntem alanında sınıf statik özellikleri tarafından başvurulan nesneler
Aşağıdaki kodda gösterildiği gibi, yığın çerçevesindeki yerel değişken a = null olduğunda, a ile gösterilen nesnenin GC Kökü (değişken a) ile bağlantısı kesildiği için, a ile gösterilen nesne geri dönüştürülecektir ve s verdiğimiz için Bir değişken referansı atanır, s şu anda sınıfın statik bir özellik referansıdır, bir GC Kökü olarak işlev görür ve işaret ettiği nesne hala canlıdır!
public class Test { genel statik Testler; public static void main (String args) { Test a = yeni Test (); a.s = yeni Test (); a = boş; } }Yöntem alanında sabitler tarafından başvurulan nesneler
Aşağıdaki kodda gösterildiği gibi, s sabitiyle gösterilen nesne geri dönüştürülmeyecektir çünkü a ile gösterilen nesne geri dönüştürülmüştür.
public class Test { public static final Test = new Test (); public static void main (String args) { Test a = yeni Test (); a = boş; } }Yerel yöntem yığınında JNI tarafından başvurulan nesneler
Bu, yerel yöntemin ne olduğunu bilmeyen çocuk ayakkabıları için basit bir açıklamadır: Sözde yerel yöntem, Java'nın java olmayan kodu çağırması için bir arayüzdür. Bu yöntem Java tarafından uygulanmaz. C veya Python gibi diğer diller tarafından uygulanabilir. Java JNI kullanır. Yerel yöntemi çağırmak için ve yerel yöntem bir kitaplık dosyası biçiminde saklanır (WINDOWS platformunda DLL dosyası, UNIX makinesinde SO dosyası). Yerel kütüphane dosyalarının dahili yöntemlerini çağırarak, JAVA yerel makine ile yakın bağlantıyı gerçekleştirebilir ve sistem düzeyinde arayüz yöntemlerini çağırabilir. Hala anlamadınız mı? Yerel yöntemlerin tanımı ve kullanımına ayrıntılı bir giriş için makalenin sonundaki referansa bakın.
Bir Java yöntemi çağrılırken, sanal makine bir yığın çerçevesi oluşturur ve bunu Java yığınına iter.Yerel bir yöntemi çağırdığında, sanal makine Java yığınını değiştirmeden tutar ve Java yığın çerçevesine yeni bir çerçeve göndermez. Makine, dinamik olarak bağlanır ve belirtilen yerel yöntemi doğrudan çağırır.
JNIEXPORT void JNICALL Java_com_pecuyu_jnirefdemo_MainActivity_newStringNative (JNIEnv * env, jobject örneği, jstring jmsg) { ... // String sınıfını önbelleğe al jclass jc = (* env) - > FindClass (env, STRING_PATH); }Yukarıdaki kodda gösterildiği gibi, java yukarıdaki yerel yöntemi çağırdığında, jc yerel yöntem yığını tarafından yığına itilecektir; jc, yerel yöntem yığınındaki JNI'nin nesne referansıdır, bu nedenle yalnızca bu yerel yöntemin yürütülmesi tamamlandıktan sonra olacaktır. yayınlandı.
Ana çöp toplama yöntemleri
Önceki bölümde, erişilebilirlik algoritmasının hangi verilerin çöp olduğunu belirlemek için kullanılabileceğini, dolayısıyla bu çöpün nasıl geri dönüştürüleceğini öğrendik. Esas olarak aşağıdaki yollar var
Mark kaldırma algoritması
Adımlar basit
İşlem gerçekten çok basit ve verileri taşımaya gerek yok Sorun nedir? Yukarıdaki resme dikkatlice bakın, evet, hafıza parçalanması! Yukarıdaki şekildeki yığın içerisine 4M veya 5M alan tahsis etmek istersek açıkça başarısız olacaktır, nasıl çözülür Yukarıdaki kullanılmayan 2M, 2M, 1M hafızaları bağlayabilirsek bağlanabilir. Sadece 5M boş alana sahip bir alana yapın, nasıl yapılır?
Algoritmayı kopyala
Yığını A ve B olmak üzere iki alana bölün. Alan A, nesnelerin tahsis edilmesinden sorumludur ve alan B tahsis edilmemiştir. Kalan nesneleri işaretlemek için yukarıda belirtilen gösterim yöntemini A alanı için kullanın (aşağıdaki şeklin silinmesine gerek yoktur) ve sonra A alanındaki tüm hayatta kalan nesneler B alanına kopyalanır (hayatta kalan nesneler sırayla yan yana düzenlenir) Son olarak, alan A'daki tüm nesneler boş alan açmak için temizlenir ve bu da bellek parçalanması sorununu çözer.
Bununla birlikte, kopyalama algoritmasının eksiklikleri açıktır: Örneğin, yığına 500M bellek tahsis edilirse, yalnızca 250M kullanılabilir ve alan hiçbir neden olmaksızın yarı yarıya azalır! Bu kesinlikle kabul edilemez! Ek olarak, hayatta kalan nesneler her geri dönüştürüldüğünde diğer yarısına taşınmalıdır, bu verimsizdir (dizi öğelerini silmeyi ve ardından silinmemiş öğeleri bir uca taşımayı düşünebiliriz, verimlilik açıkça endişe vericidir)
İşaretleme
İlk iki adım, işaret kaldırma yöntemiyle aynıdır, fark, işaret kaldırma yöntemine bir sıralama işlemi eklemesidir, yani hayatta kalan tüm nesneler, yan yana düzenlenmiş (şekilde gösterildiği gibi) bir uca taşınır ve ardından diğer uç temizlenir. Bu şekilde bellek parçalanması sorunu çözülür.
Ancak eksiklikler de açıktır: hayatta kalan nesneler, çöp her kaldırıldığında sıklıkla taşınır ve bu çok verimsizdir.
Nesil toplama algoritması
Kuşak toplama algoritması, yukarıdaki algoritmaları entegre eder, bu algoritmaların avantajlarını birleştirir ve eksikliklerinden büyük ölçüde kaçınır.Bu nedenle modern sanal makinelerin kullandığı tercih edilen algoritmadır.O kadar da bir algoritma değildir, bir strateji değildir çünkü Yukarıda bahsedilen algoritmaları entegre eder. Neden nesillere göre toplamanız gerekiyor? Nesnelerin dağılımının hangi kuralları olduğunu görelim.
Şekilde gösterildiği gibi: dikey eksen tahsis edilen baytları temsil eder ve yatay eksen program çalışma süresini temsil eder
Şekilden, nesnelerin çoğunun kısa ömürlü olduğu ve kısa bir süre içinde kurtarıldığı görülebilir (IBM profesyonel araştırması, genel olarak, Minor GC'den sonra nesnelerin% 98'inin öldüğünü göstermektedir. Geri dönüştürülecek), bu nedenle kuşak toplama algoritması, yığını nesnenin yaşam döngüsüne göre genç nesil ve eski nesil olarak ayırır (Java 8'den önce kalıcı bir nesil vardır), varsayılan oran 1: 2'dir, yeni nesil, Eden alanına bölünür. Survivor alanı (S0 olarak kısaltılır), Survivor alanına (S1 olarak kısaltılır), üçünün oranı 8: 1: 1'dir, böylece yeni ve eski nesillerin özelliklerine göre en uygun çöp toplama algoritmasını seçebiliriz. GC, Young GC (Minor GC olarak da adlandırılır) ve yaşlılıkta oluşan GC, Old GC (Full GC olarak da adlandırılır) olarak adlandırılır.
Seslendirme: Bir düşünün, yeni nesil neden bu kadar çok bölgeye sahip?
Peki, nesilsel çöp toplama nasıl çalışıyor?
Nesil toplama nasıl çalışır?
1. Yeni nesil nesnelerin tahsisi ve kurtarılması
Yukarıdaki analizden, çoğu nesnenin kısa bir süre içinde geri dönüştürüleceği ve nesnelerin genellikle Eden alanında tahsis edildiği görülebilir.
Eden alanı neredeyse dolduğunda, Minor GC'yi tetikleyin
Daha önce söylediğimiz gibi, çoğu nesne kısa sürede geri dönüştürülecek, bu nedenle Minor GC'den sonra sadece birkaç nesne hayatta kalacak ve S0 alanına taşınacaklar (bu nedenle Eden uzayının boyutu: S0: S1 = 8: 1: 1, Eden alanının S0, S1'den çok daha büyük olmasının nedeni, Eden alanında tetiklenen Küçük GC'nin nesnelerin çoğunu (% 98'e yakın) geri kazanması ve yalnızca az sayıda hayatta kalan nesne bırakmasıdır, bu yüzden onları taşıyın S0 veya S1 fazlasıyla yeterli) Aynı zamanda nesnenin yaşı bir artar (nesnenin yaşı, Küçük GC'nin oluşma sayısıdır) ve son olarak Eden alanındaki tüm nesneler, yer açmak için temizlenir. Animasyon aşağıdaki gibidir.
Bir sonraki Küçük GC tetiklendiğinde, Eden alanında hayatta kalan nesneler ve S0 (veya S1) 'de hayatta kalan nesneler (S0 veya S1'deki hayatta kalan nesneler, her Küçük GC'den sonra geri alınabilir) S1'e (Eden ve S0'ın hayatta kalan nesne yaşı +1'dir) ve Eden ve S0'ın alanı aynı anda temizlenir.
Bir sonraki Küçük GC tekrar tetiklenirse, önceki adım tekrarlanacaktır, ancak şimdi Eden'den gelir.S1 alanı hayatta kalan nesneleri S0 alanına kopyalayacaktır. Çöp toplama her seferinde, S0 ve S1 rolleri Eden'den değiştirilir. S0 (veya S1) hayatta kalan nesneyi S1'e (veya S0) taşır. Yani Eden bölgesinin çöp toplamasında çoğaltma algoritmasını kullanıyoruz, çünkü Eden alanında tahsis edilen nesnelerin çoğu Küçük GC'den sonra yok oluyor ve hayatta kalan nesnelerin sadece küçük bir kısmı kalıyor (bu yüzden Eden: S0: S1 varsayılan olarak 8: 1: 1'dir) S0 ve S1 alanları da nispeten küçüktür, bu nedenle çoğaltma algoritmasının neden olduğu sık nesne kopyalamanın neden olduğu ek yük en aza indirilir.
2. Denek ne zaman yaşlılığa yükseltilecek?
Şekilde gösterildiği gibi: yaş eşiği 15'e ayarlanmıştır. Bir sonraki Küçük GC oluştuğunda, S0'daki bir nesne 15'e ulaşır ve belirlediğimiz eşiğe ulaşır ve yaşlılığa yükseltilir!
3. Alan tahsisi garantisi
MinorGC'nin ortaya çıkmasından önce, sanal makine ilk olarak eski nesildeki mevcut en büyük sürekli alanın yeni nesildeki tüm nesnelerin toplam alanından daha büyük olup olmadığını kontrol eder. Daha büyükse, Minor GC güvenli olduğundan emin olabilir. Şundan büyük değilse sanal makine HandlePromotionFailure ayar değerinin olup olmadığını kontrol eder. Garantinin başarısız olmasına izin verin. İzin verilirse, eski nesildeki maksimum kullanılabilir sürekli alanın eski nesle yükseltilen nesnelerin ortalama boyutundan daha büyük olup olmadığını kontrol etmeye devam edecektir, eğer bundan daha büyükse, bir Minor GC gerçekleştirilecektir, aksi takdirde bir Full GC gerçekleştirilebilir.
4. Dünyayı Durdurun
Eski nesil doluysa, Tam GC tetiklenecektir Tam GC, hem genç nesli hem de eski nesli aynı anda geri kazanacaktır (yani, GC tüm yığın), bu da Dünyayı Durdur'a (STW olarak kısaltılmıştır) ve çok fazla performans yüküne neden olacaktır.
STW nedir? Sözde STW, yani GC sırasında (küçük GC veya Tam GC), yalnızca çöp toplayıcı iş parçacığı çalışıyor ve diğer çalışan iş parçacıkları askıya alındı.
Seslendirme: Çöp toplama sırasında diğer çalışan iş parçacıkları neden askıya alınır? Başka bir grup insan çöpü atarken çöp topladığınızı hayal edin Çöpler temizlenebilir mi?
Genel olarak, Tam GC, çalışan iş parçacığının çok uzun süre duraklamasına neden olur (çünkü Tam GC, tüm yığındaki kullanılamayan nesneleri temizler, bu genellikle uzun sürer), sunucu çok fazla istek alırsa, hizmet reddedilir! Bu nedenle, Tam GC'yi en aza indirmeliyiz (Küçük GC de STW'ye neden olur, ancak sadece hafif bir STW tetiklenecektir, çünkü Eden alanındaki nesnelerin çoğu geri dönüştürülmüştür ve yalnızca birkaç hayatta kalan nesne çoğaltma algoritması aracılığıyla S0 veya S1 alanına aktarılacaktır. , Yani nispeten iyi).
Şimdi anlamalıyız ki, genç nesli Eden, S0, S1 alanına ayarlamanın veya nesne için yaş eşiğini belirlemenin veya genç neslin ve eski neslin alan boyutunu varsayılan olarak 1: 2'ye ayarlamanın, nesnenin eskiye erken girmesini önlemek olduğunu anlamalıyız. Tam GC, olabildiğince geç tetiklenir. Sadece yeni nesilde Eden'i ayarlarsanız ne olacağını düşünün.Sonuç, her Minor GC'den sonra, hayatta kalan nesnelerin eski nesle erken girmesi, daha sonra eski nesil hızla dolması ve Full GC'nin yakında tetiklenmesidir, ancak nesne aslında İki veya üç Küçük GC'den sonra çoğu ölecek, bu nedenle S0 ve S1 tamponlarında sadece birkaç nesne yaşlılığa girecek ve yaşlılığın boyutu o kadar hızlı büyümeyecek, bu da erken doğmayı engelliyor Tam GC'yi tetikleyin.
Tam GC (veya Minor GC) performansı etkileyeceğinden, GC'yi uygun bir zamanda başlatmalıyız. Bu zamandaki bu noktaya Güvenli Nokta denir. Zaman içindeki bu noktanın seçimi, GC süresini çok uzun yapmak için çok küçük olmamalıdır. Program uzun süre takılı kalırsa, çalışma sırasında yükü çok fazla artırmak için çok sık olmamalıdır. Genel olarak, GC Kök bilgisinin belirlenmesi vb. Gibi zamandaki bu noktada iş parçacığının durumu, JVM'nin GC'yi güvenli bir şekilde başlatabilmesi için belirlenebilir. Güvenli Nokta, esas olarak aşağıdaki belirli konumları ifade eder:
Çöp toplayıcı türleri
Toplama algoritması bellek kurtarma metodolojisiyse, çöp toplayıcı, bellek kurtarmanın spesifik uygulamasıdır. Java sanal makine spesifikasyonu, çöp toplayıcının nasıl uygulanması gerektiğini belirtmez, bu nedenle genel olarak, farklı satıcılar tarafından sağlanan çöp toplayıcının uygulanması ve sanal makinenin farklı versiyonları farklı olabilir.Genel olarak, kullanıcıların uygulamanın özelliklerine göre ayarlamalarına izin verecek parametreler verilir. Çeşitli nesillerde kullanılan toplayıcıları birleştiren başlıca şu çöp toplayıcıları vardır.
Resimdeki çöp toplayıcının bir bağlantısı varsa, birlikte kullanılabilecekleri anlamına gelir.Şimdi, her bir çöp toplayıcının belirli işlevlerine bir göz atalım.
Senozoik toplayıcı
Seri toplayıcı
Seri toplayıcı yeni nesilde çalışır.Tek iş parçacıklı bir çöp toplayıcıdır.Tek iş parçacıklı, çöp toplamayı tamamlamak için yalnızca bir CPU veya bir toplama iş parçacığı kullanacağı anlamına gelir.Sadece bu değil, yukarıda bahsedilen STW'yi hatırlıyor musunuz? , Çöp toplama işlemi gerçekleştirirken, diğer kullanıcı iş parçacıkları, çöp toplama bitene kadar askıya alınacaktır, yani, GC sırasında, uygulama şu anda kullanılamaz.
Görünüşe göre tek iş parçacıklı çöp toplayıcı çok pratik değil, ancak bilmemiz gereken herhangi bir teknolojinin kullanımı sahneden ayrılamaz. İstemci modunda, basit ve etkilidir (diğer toplayıcıların tek iş parçacıklı toplayıcıları ile karşılaştırıldığında) ve tek bir CPU'yu sınırlayan ortama uygundur. Diğer bir deyişle, Seri tek iş parçacıklı modun diğer iş parçacıklarıyla etkileşime girmesine gerek yoktur, bu da ek yükü azaltır.GC üzerinde yoğunlaşma, tek iş parçacıklı avantajlarını en üst düzeye çıkarabilir.Ayrıca, kullanıcı masaüstü uygulama senaryolarında, sanal makinelere ayrılan bellek genellikle çok büyük değildir. , Onlarca veya hatta bir veya iki yüz megabayt toplayın (yalnızca yeni nesil bellek, masaüstü uygulamaları temelde daha büyük olmayacaktır), STW süresi 100 milisaniyeden fazla bir süre içinde kontrol edilebilir, sık sık gerçekleşmediği sürece, bu duraklama kabul edilebilir Dolayısıyla, İstemci modunda çalışan sanal makineler için, Seri toplayıcı yeni nesil için varsayılan toplayıcıdır.
ParNew toplayıcı
ParNew toplayıcı, Seri toplayıcının çok iş parçacıklı bir sürümüdür.Çoklu iş parçacığı kullanmaya ek olarak, diğer toplama algoritmaları, STW, nesne tahsis kuralları ve geri dönüşüm stratejileri, Seri toplayıcınınkilerle aynıdır. Alt seviyede, bu iki toplayıcı da aynı şeyi paylaşır Daha fazla kod, çöp toplama süreci aşağıdaki gibidir
ParNew esas olarak Sunucu modunda çalışır.Sunucu daha fazla istek alırsa yanıt süresinin çok önemli olduğunu biliyoruz.Multithreading, çöp toplamayı daha hızlı hale getirebilir, bu da STW süresini azalttığı ve yanıt süresini iyileştirdiği anlamına gelir. Yeni nesil toplayıcı, Sunucu modunda çalışan sanal makineler için ilk tercihtir.Performansla ilgisi olmayan bir başka neden de Seri toplayıcı dışında yalnızca CMS toplayıcıyla çalışabilmesidir.CMS, çığır açan bir çöp toplayıcıdır. Eşzamanlı toplayıcı anlamında, çöp toplama iş parçacığının ve kullanıcı iş parçacığının (temelde) aynı anda çalıştığını fark eder, geleneksel GC toplayıcı kod çerçevesini kullanır ve Serial, ParNew bir kod çerçevesini paylaşır, böylece Bu ikisiyle birlikte çalışın ve daha sonra bahsedilen Parallel Scavenge ve G1 toplayıcıları geleneksel GC toplayıcı kodu çerçevesini kullanmaz, ancak bağımsız olarak uygulanır. Diğer toplayıcılar çerçeve kodunun yalnızca bir bölümünü paylaşır, bu nedenle CMS toplayıcı ile çalışamaz.
Birden fazla CPU olması durumunda, ParNew'in çok iş parçacıklı geri dönüşüm özelliği nedeniyle, çöp toplamanın daha hızlı olacağına ve ayrıca STW süresini etkili bir şekilde azaltacağına ve uygulama yanıt hızını artırabileceğine şüphe yoktur.
Paralel Temizleme toplayıcı
Parallel Scavenge toplayıcı aynı zamanda bir çoğaltma algoritması kullanan, çok iş parçacıklı ve yeni nesilde çalışan bir çöp toplayıcıdır.ParNew toplayıcı ile aynı işleve sahip gibi görünüyor.Bununla ilgili özel bir şey var mı?
Odak farklıdır. CMS gibi çöp toplayıcılar, çöp toplama sırasında kullanıcı iş parçacıklarının duraklatma süresini olabildiğince kısaltmaya odaklanırken, Parallel Scavenge'ın amacı kontrol edilebilir bir verim elde etmektir (verim = çalıştırma kullanıcı kodu süresi / (kullanıcı kodu süresini çalıştırma) + Çöp toplama süresi)), yani CMS gibi çöp toplayıcıların kullanıcılarla etkileşime giren programlar için daha uygun olduğu anlamına gelir, çünkü duraklama süresi ne kadar kısaysa kullanıcı deneyimi o kadar iyi olurken, Parallel Scavenge toplayıcı verime odaklanır, bu yüzden daha uygundur Çok fazla kullanıcı etkileşimi gerektirmeyen arka plan hesaplamaları ve diğer görevleri yapın.
Parallel Scavenge toplayıcı, verimi doğru bir şekilde kontrol etmek için iki parametre sağlar. Bunlar, maksimum çöp toplama süresini kontrol eden -XX: MaxGCPauseMillis parametresi ve doğrudan işleme boyutunu ayarlayan -XX: GCTimeRatio'dur (varsayılan% 99)
Yukarıdaki iki parametreye ek olarak, Parallel Scavenge toplayıcı tarafından sağlanan üçüncü parametre -XX: UseAdaptiveSizePolicy'yi de kullanabilirsiniz.Bu parametreyi açtıktan sonra, genç neslin boyutunu, Eden'in Survivor oranını (SurvivorRatio) ve diğer ayrıntıları manuel olarak belirtmenize gerek yoktur. Temel yığın boyutunu (maksimum yığını ayarlamak için -Xmx) ve maksimum çöp toplama süresini ve verimini ayarlayın, sanal makine mevcut sistem işlemine göre izleme bilgilerini toplayacak ve kümemize mümkün olduğunca ulaşmak için bu parametreleri dinamik olarak ayarlayacaktır. Maksimum çöp toplama süresi veya işlem hacmi iki göstergedir. Uyarlanabilir strateji, Parallel Scavenge ve ParNew! Arasında önemli bir farktır.
Yaşlılık koleksiyoncusu
Seri Eski koleksiyoncu
Yukarıda bildiğimiz gibi, Seri toplayıcı, yeni nesilde çalışan tek iş parçacıklı bir toplayıcıdır.Ancak Serial Old, eski nesilde çalışan tek iş parçacıklı bir toplayıcıdır.Bu koleksiyonerin temel önemi sanal Sunucu modunda kullanılıyorsa, iki ana kullanımı vardır: biri, JDK 1.5 ve önceki sürümlerde Parallel Scavenge ile birlikte kullanılacak ve diğeri, eşzamanlı koleksiyonun gerçekleştiği CMS toplayıcı için bir yedekleme planı olarak kullanılacak. Eşzamanlı Mod Arızası olduğunda kullanılır (daha sonra açıklanacaktır), aşağıdaki gibi Seri toplayıcı ile birlikte kullanılır
Paralel Eski toplayıcı
Parallel Old, Parallel Scavenge toplayıcısının eski sürümüne göredir. Çoklu okuma ve etiket sıralaması kullanır. İkisinin kombinasyonunun şematik diyagramı aşağıdaki gibidir. İkisinin kombinasyonu, gerçekten "önce iş hacmine" ulaşan çok iş parçacıklı bir toplayıcıdır Amaçları
CMS toplayıcı
CMS toplayıcı, en kısa STW süresine ulaşmayı hedefleyen bir toplayıcıdır.Uygulama, hizmetin yanıt hızına büyük önem veriyorsa ve kullanıcılara en iyi deneyimi yaşatmak istiyorsa, CMS toplayıcı çok iyi bir seçimdir!
Daha önce yaşlılığın esas olarak işaretleme yöntemini kullandığını ve CMS'nin yaşlılıkta çalışmasına rağmen, esas olarak aşağıdaki dört adımı olan işaret kaldırma yöntemini kullandığını söylemiştik.
STW'nin ilk işaretleme ve yeniden işaretleme aşamalarında meydana geleceği ve kullanıcı iş parçacığının askıda kalmasına neden olacağı şekilden görülebilir, ancak ilk işaretleme yalnızca GC Kökleri ile ilişkilendirilebilen nesneleri işaretler ki bu çok hızlıdır Eşzamanlı işaretleme, GC Kök İzleme sürecidir. Yeniden işaretleme, eşzamanlı işaretleme sırasında kullanıcı ipliğinin devam eden işlemine bağlı olarak işaretlemesi değiştirilen nesnenin parçasının işaretleme kaydını düzeltmektir Bu aşamadaki duraklama süresi genellikle başlangıç işaretleme aşamasından biraz daha uzun, ancak eşzamanlı işaretleme süresinden çok daha kısadır.
Tüm süreçte en uzun zaman alan süreç eş zamanlı işaretleme ve işaretleme temizliğidir.Ancak, kullanıcı iş parçacıkları bu iki aşamada çalışabilir, bu nedenle uygulamanın normal kullanımını etkilemez. Bu nedenle, genel olarak CMS toplayıcısının bellek kurtarma işlemi şu şekilde değerlendirilebilir: Kullanıcı konuları eşzamanlı olarak yürütülür.
Bununla birlikte, CMS toplayıcı mükemmel olmaktan uzaktır ve aşağıdaki üç dezavantaja sahiptir.
G1 (Önce Çöp) toplayıcı
G1 toplayıcı, sunucu odaklı bir çöp toplayıcıdır.Her şeyi kontrol eden çöp toplayıcı olarak adlandırılır.Aşağıdaki özelliklere sahiptir.
CMS ile karşılaştırıldığında, aşağıdaki iki açıdan daha iyi performans gösterir
G1 neden öngörülebilir bir duraklama modeli oluşturabilir? Bunun ana nedeni, G1'in yığın alanı tahsisinin geleneksel çöp toplayıcıdan farklı olmasıdır.Geleneksel bellek tahsisi süreklidir, yeni nesillere ve eski nesillere bölünmüştür. Çağda, yeni nesil aşağıdaki gibi Eden, S0, S1'e ayrılmıştır.
Her bir G1 neslinin depolama adresleri sürekli değildir. Her nesil, aynı boyutta n ayrı bölge kullanır ve her bölge, şekilde gösterildiği gibi sürekli bir sanal bellek adresini işgal eder
Geleneksel yeni ve eski nesiller ile hayatta kalma alanı arasındaki mekansal farka ek olarak, Bölgede Humongous anlamına gelen ek bir H vardır, bu da bu Bölgelerin büyük nesneler (H-obj) depoladığı anlamına gelir, yani boyut bölgenin yarısından büyük veya yarısına eşittir. Bu şekilde, büyük boyutlu nesneler doğrudan eski nesle tahsis edilir ve tekrarlanan kopyalama ve hareketleri önler. Peki G1 tahsisinin bunun gibi faydaları nelerdir?
Geleneksel toplayıcı, Full GC oluşursa, tüm yığından çöp toplamak ve her bölgeye tahsis etmektir, G1'in her bölgedeki çöp birikiminin değerini (geri dönüşüm ile elde edilen alan miktarı ve geri dönüşüm için gerekli deneyim değeri) izlemesi uygundur. Bu şekilde değere göre öncelik listesi tutulur, izin verilen toplama süresine göre ilk olarak en yüksek geri kazanım değerine sahip bölge toplanır, bu da tüm eski neslin geri kazanılmasını engeller ve STW'nin neden olduğu duraklama süresini azaltır. Aynı zamanda sadece bazı bölgeler toplandığı için STW süresi kontrol edilebilir.
G1 toplayıcının çalışma adımları aşağıdaki gibidir
Genel sürecin CMS toplayıcısına çok benzediği görülebilmektedir Tarama aşaması her Bölgenin geri kazanım değeri ve maliyetine göre sıralanacak ve kurtarma planı kullanıcının beklediği GC duraklatma süresine göre yapılacaktır.
sonuç olarak
Bu makale çöp toplama prensibini ve çöp toplayıcıların çeşitlerini kısaca anlatmaktadır.Başlangıçta bahsedilen bazı problemleri daha derinlemesine anlamanız gerektiğine inanıyorum.Üretim ortamında, farklı senaryolara göre çöp toplayıcıların kombinasyonunu seçmeliyiz.Client Serial + Serial Old ParNew + CMS G1JVM