我在我的应用程序中运行客户端代码,就像WebServer部署/取消部署WebApps一样。
所以我创建了一个自定义ClassLoader
,它被丢弃以摆脱客户端代码。但是,这不能正常工作。使用Elipse Memory Analyzer执行和分析时,我可以看到对象和类加载器永远不会被垃圾回收:
不知何故,问题似乎与实现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。
答案 0 :(得分:1)
在尝试了其他所有内容之后,我更新了JDK并且...现在问题已经消失。现在我们使用jdk1.7.0_51
代替jdk1.7.0_09
。
希望这有助于某人...