2

这与我的问题Java Excel POI 在石英多次执行后停止有关。

几次迭代后,我的程序意外停止。我尝试进行分析,发现每次迭代都消耗了大量的堆内存(并且某个地方的内存泄漏……还没有找到问题所在)。因此,作为临时解决方案,我尝试System.gc();在程序的每次完整执行结束时插入(请阅读链接的问题以获取程序的简要说明)。我并没有期待太多,每次迭代后可能会有更多可用的堆空间。但是,当我插入System.gc();.

在此处输入图像描述

上图显示了运行的程序,System.gc();而下图是没有运行的程序。如您所见,上图显示在程序的 4 次迭代后我只使用了不到 100mb 的空间,而下图显示在相同数量的迭代中使用超过 100mb。任何人都可以澄清如何以及为什么System.gc();会在我的堆中造成这种影响?如果我在我的程序中使用它有什么缺点吗?或者我对编程完全没有希望,而是开始摄影?

请注意,我在每次程序迭代结束时插入了 GC。所以我假设堆使用必须和没有插入GC的情况一样,直到它满足System.gc();命令

谢谢!

4

3 回答 3

1

根据 Java 规范,调用 gc() 并不能保证它会运行,您只会提示 JVM 需要它运行,因此结果是不可靠的(无论如何都应该避免调用 gc())。但是,在您的情况下,由于堆逐渐达到临界极限,这就是为什么您的提示可能正在执行的原因。

GC 通常基于特定算法运行以防止堆被耗尽,当它无法回收急需的空间而没有更多堆供您的应用程序生存时,您将面临OutOfMemoryException.

当 GC 运行时,您的应用程序会由于其活动而经历一些暂停,因此您不会真的希望它更频繁地运行!

最好的办法是解决泄漏并练习更好的内存管理以获得健康的运行时体验。

于 2013-01-02T08:11:10.410 回答
1

任何人都可以澄清 System.gc() 的方式和原因吗?在我的堆中造成这种影响?

System.gc是垃圾收集器运行的一种请求服务。请注意,我在我的声明中使用了request而不是。trigger基于堆状态的 GC 可能/不进行收集。

如果我在我的程序中使用它有什么缺点吗?

根据经验,GC 在单独放置时效果最好。在您的示例中,您不必担心或使用System.gc. 因为 GC 将在最佳运行时运行,并且手动请求它可能会降低性能。即使只有很小的差异,您也可以观察到下图中的“在 gc 上花费的时间”比第一个要好。

根据记忆,两张图都可以。好像你的最大堆有点高。因此 GC 没有在第二张图中运行它。如果真的需要,它会运行它。

于 2013-01-02T08:29:34.457 回答
0

使用 System.gc() 不应影响分配给 JVM 的堆大小。堆大小仅取决于我们提供给 JVM 的启动参数。我会建议您运行相同的程序 3-4 次,并使用 System.gc() 和不使用平均值。

回到寻找内存泄漏的问题;我会推荐使用 JProfiler 或其他工具来告诉你确切的内存占用;和堆中的不同对象。

最后但是同样重要的; 你是一个合理的程序员。不需要去拍照:)

于 2013-01-02T08:21:25.283 回答