我一直在使用Eclipse内存分析工具来检查堆转储。我还没有看到任何一个对象通过线程堆栈中的局部变量保持活动的情况。
堆栈转储中是否保留了java线程堆栈?如果没有,这些对象是否被计为转储中无法访问的对象?如果是这样,有没有办法保留线程堆栈,以便可以将未收集的垃圾与局部变量值区分开来?
答案 0 :(得分:12)
是强>
来自最新JVM的堆转储(截至2010年)包括Thread Stacks。 Eclipse Memory Analyzer 0.8(2010年1月发布)包括对提取此信息的支持:http://www.eclipse.org/mat/0.8/noteworthy.html
答案 1 :(得分:6)
不保留堆栈跟踪,但保留堆栈中的对象引用。
SELECT DISTINCT * FROM OBJECTS ( SELECT OBJECTS
${snapshot}.getOutboundReferentIds(thread.getObjectId())
FROM INSTANCEOF java.lang.Thread thread )
此OQL查询选择Java线程(java.lang.Thread和子类)引用的所有对象。该集包括所有Java Local变量以及Java线程实例引用的任何其他对象。
答案 2 :(得分:1)
不,线程堆栈与堆转储是分开的。
你是如何进行堆转储的? jmap
?如果是,则默认为only live objects are dumped。这意味着您将看不到无法访问的对象。听起来你有内存泄漏或其他什么。我建议使用JVisualVM或更复杂的分析器。
答案 3 :(得分:0)
即使只有一个局部变量引用它,也确实可以访问对象。试试这个:
MyClass
main
obj = new ...
obj.doSomethingThatTakes30Minutes()
obj
shoudl出现在堆转储中。