Java'daki çöp toplayıcı nedir?


104

Java'da yeniyim ve Java'daki çöp toplayıcı konusunda kafam karıştı. Gerçekte ne işe yarar ve ne zaman eyleme geçer. Lütfen Java'daki çöp toplayıcının bazı özelliklerini açıklayın.



10
Bazen iyi bir kitaptaki bölümü okumak, karmaşık bir konuyu cevaptan bir soruya kadar anlamak daha iyidir.
Ian Ringrose

4
@ Ian Bu benzer bir soru, ancak bir kopya değil. Ve bu soru ev ödevi kokuyor .
NullUserException

Yanıtlar:


119

Çöp toplayıcı üzerinde çalışan bir programdır Java Virtual Machine artık bir Java uygulaması tarafından kullanılmayan nesnelerin kurtulur. Otomatik hafıza yönetiminin bir şeklidir .

Tipik bir Java uygulaması çalışırken, Strings ve Files gibi yeni nesneler yaratır , ancak belirli bir süre sonra bu nesneler artık kullanılmaz. Örneğin, aşağıdaki koda bir göz atın:

for (File f : files) {
    String s = f.getName();
}

Yukarıdaki kodda, döngünün String sher yinelemesinde oluşturulmaktadır for. Bu, her yinelemede bir Stringnesne oluşturmak için biraz bellek ayrıldığı anlamına gelir .

Koda geri dönersek, tek bir yineleme yürütüldüğünde, bir sonraki yinelemede, Stringönceki yinelemede oluşturulan nesnenin artık kullanılmadığını görebiliriz - bu nesne artık "çöp" olarak kabul edilir.

Sonunda, çok fazla çöp almaya başlayacağız ve bellek artık kullanılmayan nesneler için kullanılacak. Bu devam ederse, sonunda Java Sanal Makinesi'nde yeni nesneler oluşturmak için alan kalmaz.

Çöp toplayıcı burada devreye giriyor.

Çöp toplayıcı artık kullanılmayan nesneleri arar ve onlardan kurtulur, hafızayı serbest bırakır, böylece diğer yeni nesneler bu hafıza parçasını kullanabilir.

Java'da bellek yönetimi çöp toplayıcı tarafından halledilir, ancak C gibi diğer dillerde bellek yönetiminin kendi başına mallocvefree gibi işlevleri kullanarak gerçekleştirmesi gerekir . Hafıza yönetimi , hata yapması kolay şeylerden biridir ve hafıza sızıntılarına yol açabilir - hafızanın artık kullanılmadığında geri kazanılmadığı yerler.

Çöp toplama gibi otomatik bellek yönetimi şemaları, programcının bellek yönetimi sorunları hakkında çok fazla endişelenmesine gerek kalmadan geliştirmesi gereken uygulamaları geliştirmeye daha fazla odaklanmasını sağlar.


Bir bilgisayarda çalışan bir java uygulamasının iki çöp toplama işlevine sahip olduğunu söylemek doğru olur mu? Java sanal makinesi ile bir. Ve sonra pencereleri çalıştıran gerçek makinede bir tane? (Veya başka bir işletim sistemi)
Lealo

Hayır, genellikle Java uygulamaları yalnızca JRE varsa çalışır. Bu nedenle, yalnızca JVM'nin çöp toplama işlevi gereklidir! @Lealo
Am_I_Helpful

18

Artık program tarafından kullanılmayan nesnelere ayrılan belleği serbest bırakır - dolayısıyla "çöp" adı da buradan gelir. Örneğin:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Bunun aşırı derecede uydurma olduğunu biliyorum, ama burada aradıktan sonra yaratılan otherMethod()orijinali Objecterişilemez hale getirilir - ve bu da çöplerin toplanmasını sağlayan "çöp" dür.

Java'da GC otomatik olarak çalışır, ancak onu açıkça çağırabilir System.gc()ve büyük bir çöp toplamaya zorlamayı deneyebilirsiniz . Pascal Thivent'in işaret ettiği gibi, bunu gerçekten yapmanız gerekmiyor ve bu yarardan çok zarar verebilir ( bu soruya bakın ).

Daha fazla bilgi için, Garbage collection and Tuning Garbage Collection (Oracle'dan) ile ilgili wikipedia girişine bakın


1
AFAIK System.gc(), GC'yi çalışmaya zorlamaz.
Itay Karo

1
İyi kod örneği için +1. GC'nin myObjçağrı otherMethodgerçekleşmeden önce yok edilmesinin tamamen geçerli olduğunu unutmayın , çünkü myObjo noktada artık erişilebilir değildir.
Billy ONeal

@ İtalya Bunun uygulamaya özel olduğuna inanıyorum.
NullUserException

2
Birinin aramaması gerektiğine inanıyorum System.gc(), GC'ye sahip olmanın tüm amacı bunu yapmak zorunda olmamaktır.
Pascal Thivent

kaçış analizi ile ( en.wikipedia.org/wiki/Escape_analysis ), JVM'nin nesneyi bu örnekte ilk sırada tahsis edememesi bile mümkündür. Tüm nesne oluşturma (teoride) optimize edilebilir. Elbette uygulamaya bağlı.
mikera

15

Bir nesne, herhangi bir canlı iş parçacığından veya herhangi bir statik referansla erişilebilir değilse, Çöp toplama veya GC için uygun hale gelir.

Başka bir deyişle, bir nesnenin tüm referansları boş ise çöp toplama için uygun hale geldiğini söyleyebilirsiniz. Döngüsel bağımlılıklar referans olarak sayılmaz, bu nedenle A nesnesinin B nesnesine bir başvurusu varsa ve B nesnesinin A Nesnesine bir başvurusu varsa ve başka bir canlı referansa sahip değilse, hem A hem de B Nesneleri Atık toplama için uygun olacaktır.


Çöp Toplama için Yığın Üretimleri -

Java nesneleri, Java'da çöp toplama amacıyla oluşturulur Heapve Heapüç kısma veya nesile ayrılır, bunlara yığının Genç (Yeni) nesil, Tenured (Eski) Nesil ve Perma Alanı adı verilir .

Java yığın alanı Yeni Nesil ayrıca Eden alanı, Survivor 1 ve Survivor 2 alanı olarak bilinen üç bölüme ayrılmıştır. Yığın içinde ilk yaratılan bir nesne, Eden uzayında yeni nesilde yaratılır ve sonraki küçük çöp toplama işleminden sonra, bir nesne hayatta kalırsa, büyük çöp toplama o nesneyi eski veya görevli nesle taşımadan önce hayatta kalan 1'e ve ardından kurtulan 2'ye taşınır .

Java Heap'in Perm alanı , JVM'nin sınıflar ve yöntemler, Dize havuzu ve Sınıf seviyesi ayrıntıları hakkındaki Meta Verileri depoladığı yerdir.

Çöp Toplama için Yığın Üretimleri

Daha fazlası için buraya bakın: Çöp Toplama


System.gc()Veya Runtime.gc()yöntemini kullanarak bir istekte bulunabilirsiniz, ancak JVM'yi Çöp Toplama'yı çalıştırmaya zorlayamazsınız .

Java.lang.System içinde

public static void gc() {
    Runtime.getRuntime().gc();  
}

Java.lang.Runtime içinde

public native void gc();  // note native  method

Mark ve Süpürme Algoritması -

Bu, Çöp toplama tarafından kullanılan en popüler algoritmalardan biridir. Herhangi bir çöp toplama algoritması 2 temel işlemi gerçekleştirmelidir. Birincisi, ulaşılamayan tüm nesneleri tespit edebilmeli ve ikincisi, çöp nesneleri tarafından kullanılan yığın alanını geri kazanmalı ve alanı program için tekrar kullanılabilir hale getirmelidir.

Yukarıdaki işlemler, Mark and Sweep Algorithm tarafından iki aşamada gerçekleştirilir:

  1. Mark fazı
  2. Süpürme aşaması

daha fazla ayrıntı için burayı okuyun - İşaretleme ve Süpürme Algoritması


6

çöp toplayıcı, artık program tarafından ihtiyaç duyulmayan nesnelerin "çöp" olduğunu ve atılabileceğini belirtir.


6

Çöp Toplayıcı, JRE'nin başvurulmayan nesnenin bellekten kurtarılmasını sağlayan bir parçasıdır.
Genellikle, uygulamanızın belleği bittiğinde çalışır. AFAIK, nesneler ve izole edilmiş nesneler arasındaki bağlantıları temsil eden bir grafik tutar.
Performanstan tasarruf etmek için, nesiller halinde gruplandırılmış mevcut nesneler, GC bir nesneyi her taradığında ve onun üretim sayısının 1 artarak (sanırım maksimum maksimum değere, 3 veya 4) arttığını bulduğunda ve yeni nesil önce taranır. (bellekteki nesne ne kadar kısaysa o kadar büyük olasılıkla artık gerekli değildir), bu nedenle GC her çalıştırıldığında tüm nesneler taranmaz. daha fazla bilgi için bunu
okuyun .


@quantumSoup buna sahip misiniz? Sanırım bir tür çöp toplama (daha pahalı olanı) yalnızca yığın dolduğunda gerçekleşir.
Pablo Fernandez

2
@quantumSoup - bu, JRE'nin GC uygulamasına bağlıdır. Çoğu durumda, GC sürekli olarak çalışmaz . Bunun yerine, yığın dolu olduğu için uygulamanız bir nesneyi ayıramadığında çalışır. Son HotSpot JVM'leri paralel bir GC içerir, ancak varsayılan olarak etkin değildir.
Stephen C

Bu cevap, mekanizmaya çok fazla odaklanıyor. Soru, "Çöp toplayıcı nasıl çalışır?" Değil, "Çöp toplayıcı nedir" idi
Billy ONeal

@quantum: -1'inizi etkisiz hale getirdi, çünkü: Öğrenmek, yani bu sayfa ne için, değil mi? Öğrenmek için hatalar yapmanız gerekir. Hataları cezalandırmak insanların öğrenmemesine neden olur. Umarım bu noktada hemfikir olabilirsin. Ve belki burada bir hata yaptın.
erikbwork

1
@erikb: Bu mantıkla asla olumsuz oylar olmayacak. Ve görece zayıf yanıtları ayıklamak için olumsuz oylar gereklidir. OP açıkça bir başlangıçtır ve KH'nin belirli iç işleyişi sorulan soru için önemli değildir. Bu yanıt sorulan soruyu yanıtlamadığından (farklı bir soruyu yanıtlar), olumsuz oylar mükemmel şekilde gerekçelendirilir.
Billy ONeal

3

Çöp toplayıcı, bilgisayarınızın sonsuz belleğe sahip bir bilgisayarı simüle etmesini sağlar. Gerisi sadece mekanizmadır.

Bunu, bellek parçalarına artık kodunuzdan erişilemediğini tespit ederek ve bu parçaları ücretsiz mağazaya geri döndürerek yapar.

DÜZENLEME: Evet, bağlantı C # içindir, ancak C # ve Java bu bakımdan aynıdır.


Aslında, java ve C # 's GC arasındaki farkla ilgili olarak SO ile ilgili bir soru var: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException

3

Çoğu insan çöp toplama işleminin ölü nesneleri topladığını ve attığını düşünüyor.
Gerçekte, Java çöp toplama tam tersini yapıyor! Canlı nesneler izlenir ve diğer her şey çöp olarak belirlenir.

Bir nesne artık kullanılmadığında, çöp toplayıcı temeldeki belleği geri alır ve gelecekteki nesne tahsisi için onu yeniden kullanır. Bu, açık bir silme olmadığı ve işletim sistemine bellek geri verilmediği anlamına gelir. Hangi nesnelerin artık kullanımda olmadığını belirlemek için, JVM aralıklı olarak çok uygun bir şekilde işaret ve süpür algoritması denen şeyi çalıştırır.

Daha ayrıntılı bilgi için bunu kontrol edin: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx


1

Programcı olmayan birinin bile anlayabileceği en basit terimlerle ifade etmek gerekirse, bir program verileri işlediğinde bu veriler için ara veri ve depolama alanı (değişkenler, diziler, belirli nesne meta verileri vb.) Oluşturur.

Bu nesnelere işlevler üzerinden veya belirli bir boyuttan erişildiğinde, bunlar merkezi bir yığından ayrılır. Daha sonra uzun süre ihtiyaç duyulmadığında, temizlenmeleri gerekir.

Bunun nasıl çalıştığına dair internette çok iyi makaleler var, bu yüzden sadece çok temel tanımı ele alacağım.

GC temelde bu temizliği yapan işlevdir. Bunu yapmak için, herhangi bir aktif nesne tarafından referans alınmayan tablo girişlerini temizler, nesneleri etkin bir şekilde silerek, belleği kopyalar ve sıkıştırır. Bundan biraz daha karmaşık ama anladınız.

En büyük sorun, bu işlemin bazı kısımlarında genellikle tüm Java sanal makinesinin gerçekleşmesi için geçici olarak durdurulmasını gerektirmesi ve tüm bu işlemin çok işlemci ve bellek bant genişliği yoğun olmasıdır. GC'lerdeki çeşitli seçenekler ve her biri için ayar seçenekleri, bu çeşitli sorunları tüm GC süreci ile dengelemek için tasarlanmıştır.


0

Java'da (ve diğer dillerde / platformlarda) Çöp Toplama, java çalışma zamanı ortamının (JRE) artık ihtiyaç duyulmayan java nesnelerinden belleği yeniden kullanması için bir yoldur. Basit bir şekilde, JRE ilk başladığında İşletim Sisteminden (O / S) belirli bir bellek miktarı ister. JRE uygulamanızı / uygulamalarınızı çalıştırırken bu belleği kullanır. Uygulamanız bu belleği kullanarak tamamlandığında, JRE'nin "Çöp Toplayıcı" ortaya çıkar ve bu belleği mevcut uygulamalarınızın farklı bölümlerinde kullanılmak üzere geri alır. JRE'nin "Çöp Toplayıcısı", sürekli çalışan ve sistemin çöp çalıştırmalarına devam etmek için boşta kaldığı zamanları seçmeye çalışan bir arka plan görevidir.

Gerçek bir dünya benzetmesi, evinize gelen ve geri dönüştürülebilir çöplerinizi toplayan çöp adamlar olabilir ... sonunda, sizin ve / veya başkaları tarafından başka şekillerde yeniden kullanılır.


0

Çöp toplayıcı, referans sayım yöneticisi olarak görülebilir. bir nesne oluşturulursa ve referansı bir değişkende saklanırsa, referans sayısı bir artar. yürütme sırasında bu değişken NULL ile atanmışsa. o nesne için referans sayısı azaltılır. yani nesne için geçerli referans sayısı 0'dır. Artık Çöp toplayıcı çalıştırıldığında, 0 referanslı nesneleri kontrol eder ve kendisine tahsis edilen kaynakları serbest bırakır.

Çöp toplayıcı çağrısı, çöp toplama ilkeleri tarafından denetlenir.

Buradan biraz veri alabilirsiniz. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html


1
Referans sayma, GC'yi uygulamanın kötü bir yoludur. Herhangi bir büyük JVM uygulamasının bunu kullandığını sanmıyorum.
NullUserException

0

Çöp toplayıcı, jvm'nin bir bileşenidir.

İşlemci serbest kaldığında çöp toplamak için kullanılır.

Burada çöp, ana programın arka planında çalıştırdığı kullanılmayan nesneler anlamına gelir.

ana programın durumunu izlemek için.


0

Otomatik çöp toplama, yığın belleğe bakma, hangi nesnelerin kullanımda olup olmadığını belirleme ve kullanılmayan nesneleri silme işlemidir. Kullanımda olan bir nesne veya başvurulan bir nesne, programınızın bir kısmının hala o nesneye bir işaretçi tuttuğu anlamına gelir. Kullanılmayan bir nesneye veya başvurulmayan bir nesneye artık programınızın herhangi bir parçası tarafından başvurulmamaktadır. Böylece referans verilmeyen bir nesne tarafından kullanılan bellek geri kazanılabilir.

C gibi bir programlama dilinde, belleğin tahsis edilmesi ve serbest bırakılması manuel bir işlemdir. Java'da, belleğin serbest bırakılması işlemi çöp toplayıcı tarafından otomatik olarak işlenir. Daha iyi bir anlayış için lütfen bağlantıyı kontrol edin. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html


0

Çöp toplama, artık programınızda erişilemeyen nesneleri silerek yığın üzerindeki belleği otomatik olarak boşaltma işlemini ifade eder. Yığın, ücretsiz depo adı verilen bir bellektir ve Java uygulamanıza ayrılmış büyük bir kullanılmamış bellek havuzunu temsil eder.


1
Alıntı yapılmayan metin için alıntı biçimlendirmesi kullanmayın ve eğer alıntı yapılmışsa kaynağa atıfta bulunmanız gerekir.
Marquis of Lorne

0

Çöp toplamanın temel ilkeleri, gelecekte erişilemeyen bir programdaki veri nesnelerini bulmak ve bu nesneler tarafından kullanılan kaynakları geri kazanmaktır. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Avantajları

1) Bir bellek parçası hala işaretçiler varken serbest bırakıldığında oluşan hatalardan kurtarır ve bu işaretçilerden birinin referansı kaldırılır. https://en.wikipedia.org/wiki/Dangling_pointer

2) Program zaten serbest bırakılmış ve belki de zaten yeniden tahsis edilmiş bir bellek bölgesini boşaltmaya çalıştığında ortaya çıkan çift serbest hatalar.

3) Bir programın erişilemez hale gelen nesneler tarafından işgal edilen belleği boşaltmada başarısız olduğu ve bu da belleğin tükenmesine neden olabilen belirli bellek sızıntılarını önler.

Dezavantajları

1) Ek kaynakların, performans etkilerinin, program yürütülmesinde olası duraklamaların ve manuel kaynak yönetimi ile uyumsuzlukların tüketilmesi. Çöp toplama, programcı bu bilgiyi zaten biliyor olsa bile, hangi belleğin boşaltılacağına karar vermek için bilgi işlem kaynaklarını tüketir.

2) Çöpün gerçekten toplandığı an öngörülemez olabilir ve bir oturum boyunca dağınık durmalara (kayma / boş hafıza için duraklamalar) neden olabilir. Gerçek zamanlı ortamlarda, işlem işlemede veya etkileşimli programlarda öngörülemeyen duraklamalar kabul edilemez olabilir.


Oracle eğitimi http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Çöp toplama, hangi nesnelerin kullanıldığını ve hangilerinin kullanılmadığını belirleme ve kullanılmayan nesneleri silme işlemidir.

C, C ++ gibi programlama dillerinde bellek ayırma ve boşaltma manuel bir işlemdir.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

Süreçteki ilk adım markalama olarak adlandırılır. Çöp toplayıcının hangi bellek parçalarının kullanımda olduğunu ve hangilerinin kullanılmadığını belirlediği yerdir.

Adım 2a. Normal silme, başvurulan nesneleri ve işaretçileri boş alana bırakarak başvurulmayan nesneleri kaldırır.

Performansı artırmak için, referans verilmeyen nesneleri silmek ve ayrıca referans verilen kalan nesneleri sıkıştırmak istiyoruz. Başvurulan nesneleri bir arada tutmak istiyoruz, böylece yeni bellek ayırmak daha hızlı olacaktır.

Daha önce belirtildiği gibi, bir JVM'deki tüm nesneleri işaretlemek ve sıkıştırmak yetersizdir. Giderek daha fazla nesne tahsis edildikçe, nesnelerin listesi büyür ve daha uzun çöp toplama süresine yol açar.

Bu öğreticiyi okumaya devam ettiğinizde GC'nin bu zorluğu nasıl karşıladığını öğreneceksiniz.

Kısacası, üç yığın bölgeleri vardır YoungGeneration kısa yaşam nesneler için, OldGeneration uzun süre nesneler için ve PermanentGeneration örneği, sınıflar, kütüphaneler için, uygulama ömrü boyunca canlı nesneler için.


0

Nesneler yeni operatör tarafından dinamik olarak tahsis edildiğinden, bu nesnelerin nasıl yok edildiğini ve meşgul belleğin ne kadar serbest bırakıldığını sorabilirsiniz. C ++ gibi diğer dillerde, silme operatörü ile manuel olarak tahsis edilen nesneleri dinamik olarak serbest bırakmanız gerekir. Java'nın farklı bir yaklaşımı vardır; otomatik olarak ayrılmayı gerçekleştirir. Teknik olarak bilinir Çöp Toplama .

Şöyle çalışır: bir nesneye referans olmadığında, bu nesnenin artık gerekli olmadığı ve nesnenin kapladığı belleği geri alabileceğiniz varsayılır. Nesneleri C ++ 'da olduğu gibi açıkça imha etmek gerekli değildir. Çöp toplama, programın yürütülmesi sırasında düzensiz olarak gerçekleşir; Artık kullanılmayan bir veya daha fazla nesne olduğu için basitçe gerçekleşmez. Ek olarak, birçok Java çalışma zamanı uygulamasının çöp toplama konusunda farklı yaklaşımları vardır, ancak çoğu programcının program yazarken bu konuda endişelenmesine gerek yoktur.


-2

Otomatik çöp toplama, JVM'nin, çalışan program için en nihayetinde yer açmak için belirli veri noktalarından kurtulduğu veya bellekte tuttuğu bir işlemdir. Bellek önce yığın belleğe gönderilir, yani çöp toplayıcının (GC) işini yaptığı yerdir, ardından sonlandırılmasına veya tutulmasına karar verilir. Java, programcıya her zaman güvenilemeyeceğini varsayar, bu nedenle ihtiyaç duymadığını düşündüğü öğeleri sonlandırı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.