1. Çöp geri dönüşüm mekanizmasının önemi Java dilinin dikkat çekici bir özelliği, C++ programcıları için en sorunlu bellek yönetimi sorununu çözen çöp toplama mekanizmasının tanıtılmasıdır; böylece Java programcıları program yazarken artık bellek yönetimini dikkate almak zorunda kalmazlar. Çöp toplama mekanizması nedeniyle, Java'daki nesneler artık "kapsam" kavramına sahip değildir, sadece nesnenin referansı "kapsama" sahiptir.Çöp toplama, bellek sızıntısını etkili bir şekilde önleyebilir ve boşta anı etkili bir şekilde kullanabilir.
ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Çöp toplama mekanizmalarında algoritmalar Java dil spesifikasyonu, JVM'de hangi çöp toplama algoritmasının kullanılacağını açıkça belirtmez, ancak herhangi bir çöp toplama algoritması genellikle iki temel şeyi yapmalıdır: (1) işe yaramaz bilgi nesnelerini bulmak; (2) İşsiz nesnelerin kapladığı bellek alanını geri kazandırır, böylece program tekrar kullanılabilir.
1. Referans Sayma Toplayıcısı 1.1 Algoritma analizi
Referans sayma, çöp toplayıcılarda erken bir stratejidir. Bu yaklaşımda, yığındaki her nesne örneği için bir referans sayısı vardır. Bir nesne oluşturulduğunda ve nesne örneği bir değişkene atandığında, değişken sayısı 1 olarak ayarlanır. Bu nesneye referans olarak başka herhangi bir değişken atandığında, sayı 1 ile eklenir (a = b, o zaman b ile referans verilen nesne örneğinin sayacı +1'dir), ancak bir nesne örneğine referans ömrünü aştığında veya yeni bir değere ayarlandığında, nesne örneğinin referans sayacı 1 ile çıkarılır. Referans sayacı 0 olan herhangi bir nesne örneği çöp olarak toplanabilir. Bir nesne örneği çöp toplanırsa, referans verdiği herhangi bir nesne örneğinin referans sayacı eksi 1'dir. 1.2 Avantajlar ve dezavantajlar Liyakat:
Referans sayı toplayıcısı çok hızlı çalıştırılabilir ve programın çalıştırmasına entegre edilebilir. Programların uzun süre kesintiye uğratılması gerekmediği gerçek zamanlı ortamlar için avantajlıdır. Eksiklik:
Dairesel referanslar tespit edilemez. *Eğer ana nesnenin bir alt nesneye referansı varsa, alt nesne de ana nesneye referans verir. Bu şekilde, ceza sayısı asla 0 olamaz. 1.3 Referans sayma algoritması, örneğin dairesel referans problemini çözemez:
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main { public static void main(String[] args) { MyObject object1 = new MyObject(); MyObject object2 = new MyObject(); object1.object = object2; object2.object = object1; object1 = null; object2 = null; }} Son iki cümle, object1 ve object2'yi null olarak atar; bu da object1 ve object2'nin işaret ettiği nesnelerin artık erişilemediği anlamına gelir; ancak birbirine atıfta bulundukları için referans sayaçları 0 değildir, bu yüzden çöp toplayıcı onları asla geri dönüştürmez.
2. Takip Collector veya işaret ve süpürme algoritması 2.1 Kök arama algoritması
Kök arama algoritması, ayrık matematikte grafik teorisinden getirilmiştir; program tüm referans ilişkilerini bir grafik olarak ele alır; bir düğümden başlayarak, GC ROOT'tan başlayarak, ilgili referans düğümünü arar; bu düğümü bulduktan sonra bu düğümün referans düğümünü aramaya devam eder; tüm referans düğümler arandığında, kalan düğümler referanssız düğümler, yani işe yaramaz düğümler olarak kabul edilir. Java ve bu da GC Root olarak kullanılabilen 1. Sanal makine yığınında referans verilen nesneler (yerel değişkenler tablosu) 2. Metod alanında statik öznitelikle referans verilen nesne 3. Metod alanında sabit tarafından referans verilen nesne 4. Yerel Metod Yığınında Referans Edilen Nesneler (Yerel Nesneler)
2.2 İzleme algoritmasının şematik diyagramı
![]()
2.3 İşaretleyici temizleme algoritmasının analizi
Etiket temizleme algoritması, kök koleksiyonundan tarar, hayatta kalan nesneleri işaretler ve ardından yukarıdaki şekilde gösterildiği gibi etiketlenmemiş nesneleri geri dönüştürmek için tüm alanı tarar. Etiket temizleme algoritması nesneleri taşımak zorunda değildir ve sadece hayatta kalmayan nesneleri işler; bu da çok sayıda hayatta kalan nesne olduğunda son derece verimlidir, ancak etiket temizleme algoritması doğrudan hayatta kalmayan nesneleri geri dönüştürdüğü için bellek parçalanmasına neden olur.
3. Sıkıştırma algoritması veya etiket bitirme algoritması
![]()
Etiket-bitirme algoritması, nesneleri etiketlemek için etiket-temizleme algoritmasıyla aynı yöntemi kullanır, ancak temizleme sırasında farklıdır; hayatta kalmayan nesnelerin kapladığı alanı geri kazandıktan sonra tüm hayatta kalan nesneleri sol uçtaki boş alana taşır ve ilgili işaretçiyi günceller. Etiket-bitirme algoritması, etiket temizleme algoritmasına dayanır ve nesneleri hareket ettirir, bu yüzden daha pahalıdır, ancak bellek parçalanması sorununu çözer. Kompaktlaştırma algoritmasına dayalı koleksiyoncuların uygulanmasında, genellikle tutamaçlar ve tutamaçlar tabloları eklenir.
4. Kopyalama Algoritması (Sıkıştırma Toplayıcısı)
![]()
Algoritma, sapın üst yükünü aşmak ve yığın çöplerinin toplanmasını çözmek için önerilmiştir. Nesne dolduğunda, kopyalama algoritmasına dayalı çöp toplama aktif nesneyi kök kümeden tarar ve her aktif nesneyi serbest yüze kopyalar (böylece aktif nesnenin kapladığı bellek arasında boş delik kalmaz), böylece serbest yüzey nesne yüzü, orijinal nesne yüzü serbest yüz olur ve program yeni nesne yüzüne bellek tahsis eder. Başa çıkma algoritmasına dayalı tipik bir çöp toplama algoritması, yığını nesne yüzlerine ve serbest alan yüzlerine ayıran durdur-kopya algoritmasıdır ve program, nesne yüzleri ile serbest alan yüzleri arasında geçiş sırasında yürütmeyi durdurur.
5. Nesil Koleksiyoncu
![]()
Nesiller boyu çöp geri dönüşüm stratejisi, şu gerçeğe dayanırFarklı nesnelerin yaşam döngüsü farklıdır。 Bu nedenle, farklı yaşam döngülerine sahip nesneler, geri dönüşüm verimliliğini artırmak için farklı geri dönüşüm algoritmalarını benimseyebilirler.
Genç Kuşak 1. Tüm yeni oluşturulan nesneler önce genç nesle yerleştirilir. Genç neslin amacı, kısa yaşam döngüsü olan bu nesneleri mümkün olan en kısa sürede toplamaktır.
2. Yeni nesil hafıza, 8:1:1 oranına göre bir Eden bölgesi ve iki hayatta kalan (hayatta kanıj0, hayatta kanıj1) bölgesine bölünür. Bir Eden bölgesi, iki Survivor bölgesi (genel olarak). Nesnelerin çoğu Eden bölgesinde ortaya çıkar. Survivor0 alanı da dolduğunda, Eden alanı ve Survivor 0 alanı başka bir Survivor1 alanına kopyalanır, sonra Eden ve Survivor0 alanı boşalır, ardından Survivor0 alanı boşalır ve ardından Survivor0 alanı ile Survivor1 alanı değiş tokuş edilir. Yani, Survivor1 alanını boş tutmak ve benzeri.
3. Survivor 1 alanı Eden ve Survivor0'ın hayatta kalan nesnelerini depolamak için yeterli olmadığında, hayatta kalan nesneler doğrudan eski çağa depolanır. Yaşlılık da doluysa, tam bir GC tetiklenir, yani yeni nesil ve eski nesil geri dönüştürülür
4. Yeni neslin GC'si aynı zamanda Minor GC olarak da adlandırılır ve MinorGC sıklığı nispeten yüksektir (Eden bölgesi dolduğunda mutlaka tetiklenmez)
Eski Nesil
1. Genç nesilde N çöp geri dönüşümünü deneyimledikten sonra hâlâ hayatta kalan nesneler, yaşlı nesle yerleştirilecek. Bu nedenle, eski neslin uzun bir yaşam döngüsü olan bazı nesnelerde depolandığı düşünülebilir.
2. Hafıza ayrıca yeni neslinkiden çok daha büyüktür (yaklaşık oran 1:2'dir), yaşlılık hafızası dolu olduğunda Büyük GC tetiklenir, yani Tam GC, Tam GC sıklığı nispeten düşüktür, yaşlılık nesnesinin hayatta kalma süresi nispeten uzundur ve hayatta kalma oranı yüksek olur.
Kalıcı Üretim Statik dosyaları, örneğin Java sınıfları, metodlar vb. gibi dosyaları depolamak için kullanılır. Kalıcı nesiller çöp toplama üzerinde önemli bir etkiye sahip değildir, ancak bazı uygulamalar Hibernate gibi bazı sınıfları dinamik olarak üretebilir veya çağırabilir ve bu durumda, çalışma zamanı sırasında bu yeni sınıfları depolamak için nispeten büyük bir kalıcı üretim alanı ayarlanmalıdır.
3. GC (Çöp Toplayıcı)Yeni nesil koleksiyoncuların kullandığı koleksiyoncular: Serial, PraNew, Parallel Scavenge Yaşlılık Koleksiyoncuları tarafından kullanılan koleksiyoncular: Seri Eski, Paralel Eski, CMS
![]()
Seri toplayıcı (çoğaltma algoritması) Yeni nesil tek dişli kollektörler, işaretleme ve temizleme tek dişlidir ve avantajı basit ve verimli olmasıdır.
Seri Eski Toplayıcı (Etiket-Bitirme Algoritması) Yaşlı Tek İplik Toplayıcısı, Seri Toplayıcı'nın Yaşlılık versiyonu.
ParNew toplayıcı (stop-copy algoritması) Yeni nesil koleksiyoncu, çok çekirdekli CPU ortamında Serial'dan daha iyi performansa sahip olan Seriye koleksiyoncu'nun çok iş parçacıklı versiyonu olarak değerlendirilebilir.
Paralel Toplama Toplayıcı (Stop-Copy Algorithm) Yüksek veri verimliliği ve verimli CPU kullanımı için paralel koleksiyoncular. Veri taşımacılığı genellikle %99'dur ve veri kapasitesi = kullanıcı iş parçacığı süresi / (kullanıcı iş parçası süresi + GC iş parçacığı süresi). Yüksek etkileşim gerektirmeyen arka plan uygulamaları gibi senaryolar için uygundur.
Paralel Eski Koleksiyoncu (Stop-Copy Algorithm) Paralel Temizlik Toplayıcısının eski bir versiyonu, paralel bir koleksiyoncu, aktarım önceliği olan
CMS (Eşzamanlı Mark Süpürme) Toplayıcı (Mark-Clean Algoritması) Yüksek eşzamanlılık, düşük duraklama, en kısa GC kurtarma duraklama süresi, yüksek CPU kullanımı, hızlı yanıt süresi, kısa duraklama süresi ve çok çekirdekli CPU'nun yüksek yanıt süresi hedeflemesi
4. GC'nin uygulama mekanizmasıNesne farklı nesillerde işlendiği için, çöp toplama alanı ve zamanı da farklıdır. İki tür GC vardır: Scavenge GC ve Full GC.
Scavenge GC Normalde, yeni bir nesne oluşturulduğunda ve Eden'de alan için başvuru yapmadığında, Scavenge GC tetiklenir; bu da Eden alanını GC yapar, hayatta kalmayan nesneleri temizler ve hayatta kalan nesneleri Survivor alanına taşır. Sonra Survivor'ın iki bölgesini ayıklayın. GC bu şekilde genç neslin Eden bölgesinde uygulanır ve yaşlı nesli etkilemez. Çoğu nesne Eden bölgesinden başladığı ve Eden bölgesine çok fazla tahsis edilmediği için, Eden bölgesinin genel çalışması sık sık yapılır. Bu nedenle, Eden'i mümkün olan en kısa sürede özgür kılmak için burada hızlı ve verimli algoritmaların kullanılması genellikle gereklidir.
Tam Genel Kontrol Genç, Kadrolu ve Perm dahil tüm yığını organize edin. Tam GC, Scavenge GC'den daha yavaştır çünkü tüm yığının geri dönüştürülmesini gerektirir, bu yüzden Tam GC sayısı mümkün olduğunca azaltılmalıdır. JVM akort sürecinin büyük bir kısmı FullGC'nin akortlanmasıdır. Tam GC aşağıdaki nedenlerle oluşabilir: 1. Kadrolu tam yazılır 2. Perm tam yazılır 3. System.gc() çağrı olarak gösterilir 4. Heap'in alan tahsisi stratejisi, son GC'den sonra dinamik olarak değişir
5. GC ile Java da bellek sızıntısı sorunları yaşar.1. HashMap, Vector gibi statik koleksiyon sınıflarının kullanımı bellek sızıntısına en yatkın olanlardır ve bu statik değişkenlerin yaşam döngüsü uygulamanın yaşam döngüsüdür; tüm nesneler serbest bırakılamaz, çünkü her zaman Vector ve diğerleri tarafından uygulanır. Statik Vektör v = yeni Vektör(); için (int i = 1; i<100; i++) { Nesne o = yeni Nesne(); v.add(o); o = null; } Bu örnekte, kod yığınında Vector nesnesi için bir referans v ve Object nesnesi için bir referans o vardır. For döngüsünde yeni nesneler üretmeye devam ederiz, sonra bunları Vector nesnesine ekleriz ve o referansını geçersiz kılarız. Soru şu: O referansı geçersiz olduğunda, eğer GC gerçekleşirse, yarattığımız nesne GC tarafından yeniden dönüştürülebilir mi? Cevap hayır. Çünkü GC, kod yığınındaki referansları takip ettiğinde, v referansları bulur ve aşağıya doğru izlemeye devam ederseniz, v referanslarla işaretlenen bellek alanında Nesne nesnelerine referanslar olduğunu göreceksiniz. Bu, o referansı boşalmış olsa da, Nesne nesnesine erişilebilen başka referanslar olduğu ve GC'nin onları serbest bırakamayacağı anlamına gelir. Bu döngüden sonra Object nesnesinin program üzerinde etkisi yoksa Java programında bir bellek sızıntısı varsayılır. 2. Çeşitli bağlantılar, veritabanı bağlantıları, ağ bağlantıları, IO bağlantıları vb. çağrıyı yakın şekilde göstermez ve GC tarafından geri dönüştürülmez, bu da bellek sızıntısına yol açar. 3. Dinleyici kullanımı, dinleyici silindiğinde de nesne serbest bırakıldığında bellek sızıntısına neden olabilir.
|