调用垃圾收集会导致程序在java中使用较少的堆内存

时间:2013-01-02 07:20:53

标签: java garbage-collection profiling

这与我的问题Java Excel POI stops after multiple execution by quartz有关。

我的程序在几次迭代后意外停止。我尝试进行性能分析,发现每次迭代都消耗了大量的堆内存(并且在某处发生了内存泄漏......还没有找到bugger)。因此,作为临时解决方案,我尝试在程序的每个完整执行结束时插入System.gc();(请仔细阅读链接的问题以获得该程序的简要说明)。我没想到太多,每次迭代后可能还有一些堆空间可用。但是,当我插入System.gc();时,程序似乎使用较少的堆内存。

enter image description here

上图显示了使用System.gc();运行的程序,而下图则是没有的程序。正如您所看到的,顶部图表显示我在程序的4次迭代后仅使用不到100mb,而底部图表显示相同迭代次数的使用量超过100mb。任何人都可以澄清System.gc();在我的堆中如何以及为什么会导致这种效果?如果我在我的程序中使用它有任何缺点吗?或者我完全没有编程和摄影摄影?

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

谢谢!

3 个答案:

答案 0 :(得分:1)

根据Java规范,调用gc()并不能保证它会运行,你只提示你需要它运行的JVM,所以结果是不可靠的(你应该避免调用gc()无关紧要什么)。但是,在这种情况下,由于堆逐渐达到临界限制,这就是为什么你的提示可能正在被执行。

GC通常基于特定算法运行以防止堆耗尽,并且当它无法回收所需的空间而没有更多堆供您运行时,您将面临OutOfMemoryException。< / p>

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

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

答案 1 :(得分:1)

  

任何人都可以澄清System.gc()的方式和原因;在我的堆中导致这种效果?

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

  

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

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

根据内存,两个图表都可以。好像你的最大堆有点高。因此GC没有在第二张图中运行它。如果确实需要它,它就会运行它。

答案 2 :(得分:0)

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

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

最后但并非最不重要;你是一个合理的程序员。无需拍照:)