简体   繁体   English

当我在jvisualvm中转储堆时,如何删除对Runnable的“Java Frame”GC根引用?

[英]How can I remove a “Java Frame” GC Root reference to a Runnable when I dump a heap in jvisualvm?

I'm using jvisualvm to check for memory leaks in my application. 我正在使用jvisualvm来检查我的应用程序中的内存泄漏。 When I do a heap dump, sometimes several objects are being held open that should have been garbage collected. 当我进行堆转储时,有时会有几个对象被打开,应该是垃圾回收。

When I do a "Show Nearest GC Root" command on them, it shows me that the root is a class which I defined which implements the interface Runnable. 当我对它们执行“显示最近的GC根”命令时,它向我显示根是我定义的类,它实现了Runnable接口。 The reference is listed as (java frame) , which I know has something to do with threading. 引用列为(java frame) ,我知道它与线程有关。 When I expand the tree for this node, it opens up and shows <no references> . 当我展开该节点的树时,它会打开并显示<no references> So it seems pretty clear that this is not a reference I'm keeping open, but something internal to Java. 所以很明显,这不是我保持开放的参考,而是Java内部的东西。

The GC Root object listed in jvisualvm is of type AnalyticNode extends Node which in turn is Node implements Runnable . jvisualvm中列出的GC Root对象的类型为AnalyticNode extends Node ,而Node implements Runnable This root object in no way has anything to do with AWT, Swing, or any heavyweight user interface components, despite the word "frame" being used. 尽管使用了“frame”一词,但这个根对象绝不与AWT,Swing或任何重量级用户界面组件有任何关系。 In this case, the word "frame" refers to threading. 在这种情况下,单词“frame”指的是线程。

So does Java keep a reference to the last Runnable somewhere that would be holding this open? 那么Java是否会保留对最后一个Runnable的引用? Is there any way that I can tell Java to release this reference so it can be properly garbage collected for my heap dump? 有什么方法可以告诉Java发布这个引用,以便它可以正确地为我的堆转储垃圾收集?

What's going on here? 这里发生了什么?

In this context, "frame" refers to a stack frame. 在此上下文中,“帧”指的是堆栈帧。 It sounds like this Runnable , instead of (or in addition to) being the target of a running thread, is stored in a local variable in a frame on the stack of an executing thread. 听起来像Runnable ,而不是(或除了)作为正在运行的线程的目标,存储在执行线程的堆栈中的帧中的局部变量中。 It will be eligible for collection when the method associated with the frame returns. 当与框架关联的方法返回时,它将有资格进行收集。


Based on subsequent comments, my guess is that in your custom thread pool, there's a local variable to which the Runnable is assigned. 根据后续评论,我的猜测是在您的自定义线程池中,有一个分配了Runnable的局部变量。 It's probably in too large a scope (outside a loop) and is not being cleared (assigned null ) after each iteration of the loop. 它可能在一个范围太大(在循环之外)并且在循环的每次迭代之后没有被清除(指定为null )。

I can reproduce a situation that matches what is described with code like this in a worker thread: 我可以在工作线程中重现与此类代码相似的情况:

Runnable target = null;
while (true) {
  target = queue.take();
  target.run();
}

Cleaning up the declaration of target so that it is inside the loop fixes the problem. 清理target声明以使其在循环内部可以解决问题。

I'd suggest switching to an Executor implementation from core Java, or posting the relevant code of your custom thread pool if you want to fix it. 我建议从核心Java切换到Executor实现,或者如果要修复它,则发布自定义线程池的相关代码。

What did you do with the object you created? 你用你创造的对象做了什么? Did you create a thread and point it to it? 你创建了一个线程并指向它吗? In that case you must make sure the thread has been stopped by allowing the code in run() to finish running. 在这种情况下,您必须通过允许run()中的代码完成运行来确保线程已停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JVisualVM可以“堆转储”按钮释放内存吗? - Can JVisualVM “Heap Dump” button release memory? 如何在JVisualVM的堆转储中计算“大小” - How is “Size” calculated in JVisualVM's Heap Dump 将JVisualVM快照中的“分配的对象”与Java堆转储中的实例数进行比较 - Comparing “objects allocated” in a JVisualVM snapshot to number of instances in a Java heap dump 使用JVisualVM从Java中的远程应用程序获取堆转储 - Get heap dump from a remote application in Java using JVisualVM 如何在没有引用的情况下访问Java堆对象? - How can I access Java heap objects without a reference? JVisualvm:应用程序终止后如何进行堆转储? - JVisualvm:How to take heap dump after the application terminated? 我可以对堆转储文件运行Java垃圾回收吗? - Can I run Java garbage collection against a heap dump file? 如何在没有垃圾收集的情况下在Java 5上进行堆转储? - How can I take a heap dump on Java 5 without garbage collecting first? 如何从堆转储中了解Java对象是否处于tenure或eden空间中 - How can I know whether a Java object is in tenure or eden space from heap dump 如何在 IntelliJ 中分析堆转储? (内存泄漏) - How can I analyze a heap dump in IntelliJ? (memory leak)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM