我一直在使用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