【问题标题】:LinkedList Memory Leak链表内存泄漏
【发布时间】:2015-04-15 04:32:32
【问题描述】:

我正在尝试调试挂起的应用程序。该程序使用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$Nodes 没有被删除,而是累积。

程序的大致流程是:

      Queue.offer() → Queue.poll → Queue.remove(object)

为什么LinkedList 似乎在泄漏内存,我该如何防止这种情况发生?

【问题讨论】:

  • 请提供相关代码以复制问题以及有关环境的更多详细信息:Java 的版本、操作系统、用于执行 Java 应用程序的参数等...

标签: java memory-leaks linked-list queue


【解决方案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 的成本与 NON-garbage 的数量成正比,因此很容易看出,随着堆接近满,GC 的效率是非线性的。'

您可以通过以下代码在代码点中调用垃圾收集器: 'system.GC();'

【讨论】:

  • 非常警惕依赖System.gc():stackoverflow.com/questions/2414105/…
  • 你永远不应该调用System.gc()...永远...这会触发一个major GC,它通常应该很少发生。这样做非常昂贵,而且通常(总是?我 90% 肯定总是,但不确定所有算法)是一个停止世界的事件。如果您曾经调用它,则意味着您正在尝试清理所有堆,并且您预计会出现大量吞吐量延迟
猜你喜欢
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 2020-05-11
  • 2019-07-11
  • 2012-12-13
  • 2014-09-19
  • 2019-09-13
相关资源
最近更新 更多