Java使用的堆RAM使用高峰,我该如何避免它们?

时间:2016-09-12 09:01:58

标签: java memory-management ram visualvm jvisualvm

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

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

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

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

我知道(目前正在使用,没有注意到任何巨大的改进)Heap Tuning Paremeters,但我不认为这些可以解决问题,他们在特定点帮助,并略微减少记忆消费,但没有解决问题。

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

谢谢大家。

3 个答案:

答案 0 :(得分:2)

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

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

我的猜测是你的程序正在创建大量的对象,之后会很快被丢弃(我猜你有那些调用System.gc()的原因)。并猜测:在高费率上创建垃圾是一个坏主意。因为它可以让你的GC不断旋转;它(显然?!)有助于高内存负载。

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

答案 1 :(得分:2)

我找到了解决方案:

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

删除System.gc()为我解决了这个问题

enter image description here 谢谢MrSmith42和GhostCat。

答案 2 :(得分:1)

System.gc()不直接触发垃圾收集它更像是对VM的提示,您认为执行垃圾收集会是一个好主意。您的VM所做的是基于实现的自己的决定。 只有当VM耗尽内存时,它才会确保执行垃圾收集,但也不会调用System.gc()。 关于这个主题的很长时间的讨论可以在这里找到:

When does System.gc() do anything