我正在尝试调试挂起的应用程序。该程序使用一个用LinkedList
实现的队列,在压力测试期间,我发现程序因堆内存不足而停止响应。我分析了堆转储,发现内存似乎从LinkedList
泄漏。
堆转储的相关部分:
▶java.net.Vectior @ 0xff5eacd0
▶▶java.util.Vector @ 0xff629f30
▶▶▶java.lang.Object[1280] @ 0xff629f50
▶▶▶▶class com.itnade.vsm.staticobject.TrapQueue @ 0xff6b23e8
▶▶▶▶▶java.util.LinkedList @ 0xff6b2460
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb954560
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb959968
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb95ede8
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb964230
▶▶▶▶▶▶java.util.LinkedList$Node @ 0xfb969638
...
...
正如您在转储中看到的那样,LinkedList$Node
未被删除并累积。
该计划的一般流程是:
Queue.offer()→Queue.poll→Queue.remove(object)
为什么LinkedList
似乎在泄漏内存,我该如何防止这种情况发生?
答案 0 :(得分:1)
根据How to handle memory Leaks while continuous insertion in a LinkedList?:
你的问题不会通过显式删除对象来解决......主要是因为在Java中无法做到这一点。
'如果您确实为CMS收集器创建了太多垃圾来处理,那么唯一的解决方案是使用对象池来回收缓冲区对象而不是将它们放在地板上以便GC处理用。但是,您需要小心不要将其当前问题替换为其他人:
The recycled objects may need to be "cleaned" (zeroed).
A poorly designed object pool can be a memory leak.
A poorly designed object pool can be a concurrency bottleneck.
A poorly designed object pool can increase GC overheads, especially if you are running with a heap that is too small.
另一方面,您真正的问题可能是您的堆太小而无法运行您正在运行的应用程序。如果你的运行距离太近,GC每次都不会收回太多的垃圾。由于运行GC的成本与非垃圾量成正比,因此很容易看出,当堆接近满时,GC的效率是非线性的。'
您可以通过以下代码在代码点调用垃圾收集器: ' System.gc()的;'