终结器未针对ThreadPoolExecutor完成,导致内存泄漏

时间:2014-09-18 13:06:53

标签: java memory-leaks

我在我的应用程序中运行客户端代码,就像WebServer部署/取消部署WebApps一样。

所以我创建了一个自定义ClassLoader,它被丢弃以摆脱客户端代码。但是,这不能正常工作。使用Elipse Memory Analyzer执行和分析时,我可以看到对象和类加载器永远不会被垃圾回收:Path to Memory Leak

不知何故,问题似乎与实现ThreadPoolExecutor方法的finalize()有关。有人提到elsewhere,终结器方法是邪恶的并且可能导致OutOfMemoryErrors,因为Finalizer线程以较低的优先级运行。但是,在使用VisualVM分析应用程序和线程堆栈时,Finalizer线程并不忙,而是等待新工作到达:

"Finalizer" daemon prio=5 tid=0x00007fdb1484f800 nid=0x2603 in Object.wait() [0x000000010aaf6000]
java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x000000079aaadf10> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
 - locked <0x000000079aaadf10> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
 at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)

Locked ownable synchronizers:
 - None

ReferenceQueue.remove(ReferenceQueue.java:135)的JavaDoc:

Removes the next reference object in this queue, blocking until either 
one becomes available or the given timeout period expires.

任何可能导致此问题的想法以及如何应对?每一个输入都受到高度赞赏!

修改:我们正在使用jdk1.7.0_09.jdk,所以我猜它与this bug无关。

编辑:当我让应用程序运行足够长时间(并执行并丢弃足够的客户端代码)时,我确实得到OutOfMemoryErrors,因此VM应该垃圾收集类。另外,使用-verbose:gc标志,在类准备完成之后,在获取HeapDump之前,我会看到以下日志输出:

[Full GC 57007K->52790K(149544K), 0.2997010 secs]

这意味着,刚刚发生了一个完整的GC。

1 个答案:

答案 0 :(得分:1)

在尝试了其他所有内容之后,我更新了JDK并且...现在问题已经消失。现在我们使用jdk1.7.0_51代替jdk1.7.0_09

希望这有助于某人...