【发布时间】: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