2010-09-08 46 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