2010-09-08 81 views
13

我一直在使用Eclipse內存分析工具來檢查堆轉儲。我沒有看到任何情況下,線程堆棧中的局部變量使對象保持活動狀態。Java堆轉儲是否包含線程堆棧

Java堆棧是否保存在堆轉儲?如果不是,那麼這些對象會被計爲轉儲中不可到達的對象嗎?如果是這樣,是否有任何方法來保留線程堆棧,以便可以將未收集的垃圾與局部變量值區分開來?

回答

1

不,線程堆棧與堆轉儲是分開的。

你是如何進行堆轉儲的? jmap?如果是這樣,默認情況下,only live objects are dumped。這意味着你不會看到無法訪問的對象。聽起來像你有內存泄漏或什麼的。我會推薦使用JVisualVM或更復雜的分析器。

0

即使只有一個局部變量引用它,對象也是可以訪問的。試試這個:

MyClass 
    main 
     obj = new ... 
     obj.doSomethingThatTakes30Minutes() 

obj shoudl出現在堆轉儲中。

6

堆棧跟蹤未被保留,但堆棧中的對象引用被保留。

SELECT DISTINCT * FROM OBJECTS (SELECT OBJECTS 
${snapshot}.getOutboundReferentIds(thread.getObjectId()) 
FROM INSTANCEOF java.lang.Thread thread) 

此OQL查詢選擇Java線程(java.lang.Thread和子類)引用的所有對象。該集合包括所有Java本地變量以及Java線程實例引用的任何其他對象。

+0

您的查詢在'visualvm'和'jhat'中有語法錯誤。你能修好它嗎? – gavenkoa 2014-12-08 14:47:37

+0

似乎這是針對Eclipse MAT的查詢。 – gavenkoa 2014-12-08 14:51:05