2010-08-11 23 views
6

Bir GUI tarayıcısı uygulamasına, bir GUI eklediğim/kaldırdığım, bu nesneler için belleğin yayınlanmadığı ve üzerlerine ne tuttuğunu izlemeye çalıştığım bir hatayı içeren bir hata uygulamasına sahibim. Sorun şu ki, bir şey gerçekten hafızadan tamamen çıktığında nasıl anlatacağımı bilmiyorum.Bir Java nesnesinin belleği ne zaman serbest bırakılır?

Nesnenin bellekten çıkıp çıkmadığını anlamanın bir yolu var mı? Anlatmak için çeşitli yollar olan Objective-C'ye alışkınım.

Teşekkür

+0

(FWIW, genellikle bir dinleyicidir.) –

+0

Olduğunu düşündüm ama tüm actionListeners ve componentListeners kaldırmaya çalıştım – Shizam

cevap

6

Finalizatörlerden bahseden tüm cevaplar, peşinde olduğunuz şey değil. Eğer başvuru elde edene kadar

yapabileceğiniz en iyi bir bir ReferenceQueue içinde PhantomReference ve anket enqueue olduğunu.

final ReferenceQueue rq = new ReferenceQueue(); 
final PhantomReference phantom = new PhantomReference(referenceToObjectYouWantToTrack, rq); 

Burada Peter Kofler cevabını okumak istiyorum (bir PhantomReference ne olduğunu açıklar):

Have you ever used Phantom reference in any project?

Çok ilginç burada okuyun:

http://www.kdgregory.com/index.php?page=java.refobj

Temelde, Ne zaman bir çok özel tür önbellek hesaplanması gereken bir projede bir PhantomReference kullanıyorum yazılım yüklüdür. Bu (disk tabanlı) önbelleği verimli bir şekilde hesaplamak için devasa miktarda bellek gerekir (daha iyi). Bu devasa miktardaki bellek bittiğinde "neredeyse tam olarak" izlemek için bir PhantomReference kullanıyorum.

+0

İyi bilgi ve bağlantılar, Peter bir profiler kullanarak önerir. – Shizam

+0

Sonlandırıcıların PhantomReferences'ın çözemediği bir problem olmadığından cevabımı güncelledim. Sonlaştırıcıların OP'nin yapmaya çalıştığı şey için "yeterince iyi" olduğunu düşünüyorum, ancak yarı amaca yönelik teknikleri teşvik etmemem gerektiğini anlıyorum. –

+0

Şimdiye kadar denediğim profilciler, tek bir nesnenin serbest bırakılıp bırakılmadığını gösterme kararlılığına sahip değiller. Görünüşe göre bu cevap (PhantomReferences) en iyi araç olabilir ama sadece serbest bırakılan nesneleri izlemek için nasıl kullanılacağına dair bir örnek bulmakta zorlanıyorum. Kdgregory'deki örnek, SQL bağlantılarını izlemek için kullanıyor. Tam olarak null değerler, referenceQueue veya başka bir izleme listesi için ne yoklarım? – Shizam

3

Düzenleme:

NoozNooz42 işaret ettiği gibi, bir PhantomReference sorun 'finalizers burada olmadan, sonlandırıcı geleni, yapabilir. Bu yüzden, finalize()'u genişletmek için PhantomReferences'u kullanmaya teşvik ediyorum. Java programcılarının en azından finalize()'un var olduğunu bilmesi gerektiğini düşündüğümden beri, orijinal göndergemi koruyorum.

Orijinal Mesaj:

Her Java sınıfı başka nesneler bu sınıfın bir başvuru tutun çalıştırılacak alır bir finalize() yöntemi vardır. Öyle gibi bu yöntemi uzatabilirsiniz: şey söz konusu Nesneler bir başvuru tutarsa ​​

protected void finalize() throws Throwable { 
    try { 
     // Do whatever you want 
    } finally { 
     super.finalize(); 
    } 
} 

Böyle yaparak, sen anlamaya olabilir. Bu yaklaşımı kullanırsanız, her zaman super.finalize()'u aradığınızdan emin olun. sonuçlandırılması üzerinde

Referans:

http://java.sun.com/developer/technicalArticles/javase/finalization/

+2

Nesneler gerçekten toplandıklarında garanti vermedikleri için, finalleştiriciler Java'dan kaçınılmalıdır. Ayrıca, sonuçlandırma yalnızca örnek toplama için uygun olduğunda çalışır. Normalde problemli nesneler hafızada başka bir örnek tarafından tutulur, böylece sonuçlandırma yardımcı olmaz. Ayrıca bakınız: http://my.safaribooksonline.com/0201310058/ch02lev1sec6 (Josh Bloch tarafından etkili Java) –

+0

@jwachter: İyi nokta, ancak bağlantınızın okunması için oturum açmayı gerektirir. –

+0

@Justin Ardini: sonlandırma gerçekleşir ** ÖNCE ÖNCE ** bir nesne GC'ed. Cevabımı gör: OP, PhantomReference'dan sonra, finalizer değil. – NoozNooz42

1

YourKit deneyin. Bellek kullanımınızı ve ne halt edildiğini size gösterebilen bir Java uzmanıdır. IIRC, ücretsiz deneme Eclipse ile entegre olabilir ve ücretli sürümün tüm özelliklerine sahiptir (sadece bir zaman sınırı vardır).

3

Bellek sızıntılarını algılamanın birçok yolu vardır. İşte şu anda düşünüyorum üç: uygulamanıza bir Profiler ekleme

  1. (Netbeans veya Eclipse TPTP burada kullanışlı olmalı)
  2. bir yığın dökümü yapma ve olan bir sınıf ne örnekleri (Eclipse Memory Analyzer ile) analiz diğer örneklerin bellekte tutulması.
  3. Çöp Toplama durumunu izlemek için VisualVM eki. Java'da gerçekten yapamazsınız.
+0

ama soru herhangi bir bellek ** sızıntı ** bahsetmedi. OP sadece bir nesne GC'ed olduğunda izlemek ister. – NoozNooz42

+0

Maalesef # 1, uygulamam için hiç çalışmadı, asla nedenini çözmedi. VisualVM'yi de kontrol edeceğim, şu anda YourKit'i deniyorum. – Shizam

+0

@ NoozNooz42 haklısınız. Ama sanırım normalde sadece bir hafıza problemi olduğunda bir şey toplandığında ararsınız. –

İlgili konular