0

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

泄漏

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

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

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

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

4

3 回答 3

2

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

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

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

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

于 2013-09-06T10:26:49.600 回答
1

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

我建议从调整Eden 空间Survivor 空间的大小开始。

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

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

于 2013-09-06T10:29:54.717 回答
0

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

于 2013-09-06T10:28:03.530 回答