【问题标题】:Memory leak in Java applicationJava 应用程序中的内存泄漏
【发布时间】:2013-09-06 10:15:45
【问题描述】:

我有一个应用程序,其中使用 SSL。该应用程序的重点是它将无限运行。现在的问题似乎是,随着时间的推移,我得到了以下图像:

现在开始,我在 2 个点查看堆转储(使用 eclipse 中的内存分析器工具):1 当我的应用程序达到内存使用的最高点和最低点时(我认为是垃圾收集发生了。)一开始一切都很好,我的应用程序在终结器队列中有几个对象,这些对象消失了。但是半小时后,没有明显的原因,当垃圾收集发生时,对终结器类的引用并没有消失。它们的大小不断增加,并且有 10 个引用,它们指向一个对象和队列中的下一个终结器,它们不断重复出现。所以它实际上是一个重复链,对相同事物的引用,永远不会被收集。虽然这确实在一开始就被收集了。

所以我的问题实际上是 2 倍:第一个问题:这可能是什么原因突然没有被收集? (因为我已经非常仔细地查看了我的代码,我相当肯定我确实关闭了终结器类引用的东西(显然,输入流和输出流。还有一些来自我正在使用的 SSL 库的抽象内容,但相当肯定那里没有什么可以关闭的。我使用的是一般的 Client.getConnectionManager().shutdown(),我认为应该清除它,它在一开始就这样做了)。可能是,当应用程序重复时自己一遍又一遍,由于某种原因,引用队列太大而收集器无法处理它?

第二个问题是:我该如何解决这个问题?您看到的图像是来自 Jconsole 的顺便说一句,当我执行手动 GC 时,这些都消失了,然后重新开始。

非常感谢任何朝着正确方向的帮助或推动。

【问题讨论】:

  • when i perform the manual GC, these do all dissapear, and start over. 那就不是内存泄漏了,可能GC认为内存足够了,没有收集对象。
  • Could it be, that while the app repeats itself over and over, that for some reason the reference queue got too big and the collector just can't handle it? 如果对象被添加到终结器队列的速度比终结器线程处理它们的速度更快,那肯定会发生这种情况
  • 哦...那我看到的上下波动是什么?我的印象是,我的应用程序为对象分配内存,直到 40MB,然后被 GC 处理。不是这样吗?我认为手动和自动 GC 之间可能存在差异...
  • 第一次 GC 收集统计信息以优化其工作。在它有足够的统计数据后,它不会收集所有对象,而是收集其中的一些。它允许加速应用程序牺牲一些内存。
  • 您需要等待更长的时间才能看到堆内存发生了什么。刚刚查看了最大内存限制:1 851 392 kb。当 Gc 有大约 2 GB 的空闲堆时,它不会真正为 20-30 MB 烦恼

标签: java memory-leaks garbage-collection


【解决方案1】:

我怀疑你根本没有内存泄漏。你所拥有的是一个不需要进行完整收集的垃圾收集器。不是要减少程序的性质,但它确实很小,而且您运行它的时间不长。当然不足以确认是否有泄漏。

到目前为止,您看到的内存变化只是“清理”,还没有任何严重的收集。给 GC 一个机会来完成它的工作。

通常,只有在内存压力存在时才会发生任何严重的收集,因此当您的堆的各个部分已满时,预计会发生更积极的收集。现在你甚至还没有接近。

具体来说,你告诉java它可以使用大约90MB的内存,而你目前只使用了25MB....有什么问题?

【讨论】:

  • 我必须承认,我对此的了解相当有限。我的印象是 GC 已经定期发生(每次线路出现故障时),并且内存使用量正在缓慢上升,最终给我 OutOfMemory 错误。测试还在进行中,我看看会发生什么。
【解决方案2】:

如果full GC清除情况并将底部内存使用量移回最初的10MB,这意味着Eden空间 / Survivor空间 太小和/或对象太早被提升到老年代(这意味着它们只会在发生 Full GC 时被收集)。

我建议从调整伊甸园空间幸存者空间的大小开始。

查看 Tuning Garbage Collector documentationJava VM Options 以获取 XX:NewRatioXX:SurvivorRatio 等标志以及调整垃圾收集的其他标志。

另请阅读XX:InitialTenuringThresholdXX:MaxTenuringThreshold - 这两个定义了将对象放入旧代的阈值。如果使用得当,这两个可以使您的对象在幸存者空间中停留的时间更长,并且在没有Full GC的情况下被收集。

【讨论】:

    【解决方案3】:

    不一定是内存泄漏。我确实在连续运行数月的程序中发现了这种波动。一旦发生垃圾收集,它就会回到正常阶段。我不确定,但有时我发现使用分析器会使波动剧烈。

    【讨论】:

      猜你喜欢
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 2011-05-01
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多