我有一个 java 程序,它不断调用 java.util.zip
来压缩/解压缩数据。它会在几秒钟内耗尽内存。
我使用 jmap
进行了内存转储,我正在使用 jhat
查看它。
Finalizer 摘要显示 Total instances pending finalization: 0
。如果我理解正确,我没有任何对象 (1) 有 finalize() 方法,(2) 已被 GC 标记,(3) 正在等待完成。这看起来不错。
当我查看特定对象时,对该对象的唯一引用是 java.lang.ref.Finalizer
。 Finalizer 对象是为每个具有 finalize() 方法的对象创建的,无论该对象是否被 GC 处理过。所以看起来没有什么能阻止这个 Deflater
对象被 GC 处理。
Object at 0x7f4aeb7a35d0
instance of java.util.zip.Deflater@0x7f4aeb7a35d0 (51 bytes)
References to this object:
java.lang.ref.Finalizer@0x7f4aeb8607c8 (64 bytes) : field referent
程序在 System.in.read()
的运行中暂停。一段时间后内存使用率不会下降。
更新:
我应该说清楚。内存转储显示许多对象没有被 GC,但没有其他对象(Finalizer 对象除外)引用它们。我试图找出为什么他们没有被 GC。
最佳答案
您确定您关闭了流并在 deflater 上调用了 end
吗?如果这是您已经尝试过的简单化建议,我很抱歉,但是当使用 Deflater
而不是立即调用 end
时,有很多关于内存泄漏的提示它,例如:
- http://www-01.ibm.com/support/docview.wss?uid=swg21227106
- http://bugs.sun.com/view_bug.do?bug_id=6734186 (1.5)
- excessive memory use by java
- http://bugs.sun.com/view_bug.do?bug_id=4797189
- http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6293787
- http://kohsuke.org/2011/11/04/quiz-answer-memory-leak-in-java/
根本原因显然是当涉及 native 元素使用的内存时,收集器无法跟上应用程序。这也解释了您在分析时看到的行为:内存已准备好回收,但回收速度不够快。
由于您写道,您没有直接使用 Deflator
,而是通过 Apache Thrift,尝试确定该库中的哪个方法负责结束 deflator,并确保您调用了该方法。
关于java - 为什么 GC 不收集我的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13500132/