Eri*_*son 5 java garbage-collection memory-leaks jvisualvm
我用来jvisualvm检查应用程序中的内存泄漏。当我进行堆转储时,有时会出现几个本应被垃圾收集的对象处于打开状态。
当我对它们执行“显示最近的 GC Root”命令时,它显示根是我定义的一个类,它实现了 Runnable 接口。参考文献被列为(java frame),我知道这与线程有关。当我展开该节点的树时,它会打开并显示<no references>。因此,很明显,这不是我公开的参考资料,而是 Java 内部的东西。
jvisualvm 中列出的 GC Root 对象的类型AnalyticNode extends Node为Node implements Runnable。尽管使用了“框架”一词,但该根对象与 AWT、Swing 或任何重量级用户界面组件没有任何关系。在这种情况下,“框架”一词指的是线程。
那么,Java 是否会在某个地方保留对最后一个 Runnable 的引用,以使其保持打开状态?有什么方法可以告诉 Java 释放此引用,以便可以为我的堆转储正确收集它的垃圾吗?
这里发生了什么?
在本文中,“帧”指的是堆栈帧。听起来像是这样Runnable,而不是(或除了)作为正在运行的线程的目标之外,它存储在正在执行的线程的堆栈上的帧中的局部变量中。当与框架关联的方法返回时,它将符合收集条件。
根据后续评论,我的猜测是在您的自定义线程池中,有一个Runnable分配给的局部变量。null它可能处于太大的范围内(在循环之外),并且在循环的每次迭代后没有被清除(分配)。
我可以重现与工作线程中类似代码所描述的情况相匹配的情况:
Runnable target = null;
while (true) {
target = queue.take();
target.run();
}
Run Code Online (Sandbox Code Playgroud)
清理 的声明,target使其位于循环内可以解决问题。
我建议切换到Executor核心 Java 的实现,或者如果您想修复它,则发布自定义线程池的相关代码。
| 归档时间: |
|
| 查看次数: |
3474 次 |
| 最近记录: |