我一直在使用Eclipse內存分析工具來檢查堆轉儲。我沒有看到任何情況下,線程堆棧中的局部變量使對象保持活動狀態。Java堆轉儲是否包含線程堆棧
Java堆棧是否保存在堆轉儲?如果不是,那麼這些對象會被計爲轉儲中不可到達的對象嗎?如果是這樣,是否有任何方法來保留線程堆棧,以便可以將未收集的垃圾與局部變量值區分開來?
我一直在使用Eclipse內存分析工具來檢查堆轉儲。我沒有看到任何情況下,線程堆棧中的局部變量使對象保持活動狀態。Java堆轉儲是否包含線程堆棧
Java堆棧是否保存在堆轉儲?如果不是,那麼這些對象會被計爲轉儲中不可到達的對象嗎?如果是這樣,是否有任何方法來保留線程堆棧,以便可以將未收集的垃圾與局部變量值區分開來?
是
堆從最近的JVM(截至2010年)包括線程堆棧轉儲。 Eclipse Memory Analyzer 0.8(2010年1月發佈)包含對提取此信息的支持:http://www.eclipse.org/mat/0.8/noteworthy.html
不,線程堆棧與堆轉儲是分開的。
你是如何進行堆轉儲的? jmap
?如果是這樣,默認情況下,only live objects are dumped。這意味着你不會看到無法訪問的對象。聽起來像你有內存泄漏或什麼的。我會推薦使用JVisualVM或更復雜的分析器。
即使只有一個局部變量引用它,對象也是可以訪問的。試試這個:
MyClass
main
obj = new ...
obj.doSomethingThatTakes30Minutes()
obj
shoudl出現在堆轉儲中。
堆棧跟蹤未被保留,但堆棧中的對象引用被保留。
SELECT DISTINCT * FROM OBJECTS (SELECT OBJECTS
${snapshot}.getOutboundReferentIds(thread.getObjectId())
FROM INSTANCEOF java.lang.Thread thread)
此OQL查詢選擇Java線程(java.lang.Thread和子類)引用的所有對象。該集合包括所有Java本地變量以及Java線程實例引用的任何其他對象。
您的查詢在'visualvm'和'jhat'中有語法錯誤。你能修好它嗎? – gavenkoa 2014-12-08 14:47:37
似乎這是針對Eclipse MAT的查詢。 – gavenkoa 2014-12-08 14:51:05