我在下午7:41採用Java堆轉儲,我正在使用Eclipse內存分析工具進行分析。堆轉儲包含20個會話對象。堆轉儲中不可能的Java內存引用
在堆中的這些會話對象之一上使用GC根路徑命令顯示以下3個會話對象的引用。
- 來自Finalizer線程擁有的「未終止」鏈接列表的終結器引用。我的對象是第三行定稿。
- 從消息處理程序線程強烈引用會話對象,該線程本身是從計劃在晚上7:11運行的清理TimerTask引用的。
- 對WeakHashMap $ Entry中會話對象的弱引用。 WeakHashMap由一個靜態強參考保持活着。
如果會話對象仍然存在強和弱引用,它們如何處於終結器隊列中?
其餘19個會話對象中,還有1個在終結器隊列中,並且具有類似的弱引用。所有其他18個會話對象僅被弱引用。 GC爲什麼沒有清除這些虛弱的參考?
幾個基本點:後的弱裁判已被清除
- 對象只能享有定稿(http://download.oracle.com/javase/6/docs/api/java/lang /ref/package-summary.html)
- 會話對象沒有一個終結器,它可能會重新生成它,即使它已經在對象仍然處於其他對象後面的未終止隊列中時不能運行。
- 我的應用程序沒有使用Phantom refs,這是唯一一個對象有資格完成時應該能夠存在的引用。即使我的應用程序確實使用幻影參考,這些對象也不會將其對象所在的對象引用。
你是否確實有一個會話對象在它仍然可達時完成了?如果沒有,那麼我不會擔心它。排隊等候並不一定意味着它將被定稿,而強大的和/或弱的參考文獻仍然存在。 – finnw 2011-01-13 12:52:02
什麼機制可以阻止終結器隊列中的對象被終結?如果對象不符合條件,則這些對象不應位於此隊列中。 – mchr 2011-01-13 13:22:11
這在[Cowan的答案]中解釋過(http://stackoverflow.com/questions/4680081/impossible-java-memory-references-in-heap-dump/4759026#4759026)。 – finnw 2011-01-21 14:13:38