Java Used Heap RAM 使用高峰,如何避免?

Java Used Heap RAM usage peaks, how can I avoid them?

首先,我真的不能展示代码,对不起,这些软件是我工作的公司的,不是我的。我会尽力解释我的问题。

我正在开发一个基于 JavaFX 的小应用程序,它在 LineCharts 中显示值,每 800ms-1000ms(0.8-1 秒)刷新一次,每次刷新时调用 System.gc() (大约每 0.8-1 秒一次)。

我每 10-20 秒就有一次 RAM 使用高峰:

在这个具体的例子中,这看起来不像是一个问题,但在某些情况下它会上升到 700-750 MB(使堆大小上升到 1.2-1.3 GB,并且需要很长时间才能将其释放回OS).

我知道(并且目前正在使用,没有注意到任何巨大的改进)Heap Tuning Paremeters,但我认为这些不能解决这里的问题,它们在特定点上有帮助,并略微减少内存消费,但解决不了问题。

关于如何设计我的代码不具有这些 RAM 峰值的任何想法?我没有使用内存并每 10-20 秒释放一次内存的进程,所以我假设还有其他分配和释放大量 RAM 的东西(也许是 JavaFX?),JVisualVM 只说 int[]、byte[] 和char[],我什至没有在我的代码中使用整数值(我在这个软件中使用双精度值)。

谢谢大家

抱歉,这里唯一合理的答案是:您必须进行 分析 才能了解这些峰的来源。您必须确定此问题的根本原因;这就是我们可以提供帮助的 nothing

此程序在您的设置中运行,使用您的数据,并显示需要随时间分析的行为。

我的猜测是您的程序正在创建大量对象,这些对象随后会很快被丢弃(我猜您在那里调用 System.gc() 是有原因的)。猜猜是什么:以高速率创建 garbage 是个坏主意。因为它让你的 GC 不断旋转;它(显然?!)会导致高内存负载。

因此,如前所述:您必须确定根本原因并加以解决。从这个意义上讲:您必须研究您正在使用的工具。分析的替代方法可能是让 GC 记录其活动;并分析该输出。有关这方面的一些信息,请参阅 here

System.gc() 不会直接触发垃圾回收,它更像是向 VM 提示您认为执行垃圾回收是个好主意。您的 VM 所做的是基于实现的自己的决定。 只有当 VM 内存不足时,它才会执行垃圾收集,但也不需要您调用 System.gc()。 可以在此处找到有关此主题的相当长的讨论:

When does System.gc() do anything

我找到了解决方案:

MrSmith42 和 GhostCat 都指出调用 System.gc() 在这里对我没有真正帮助。他们是对的,事实上,这就是问题所在。

删除 System.gc() 解决了我的问题

谢谢 MrSmith42 和 GhostCat。