VisualVM 堆大小不遵循已用大小

VisualVM heap size doesn't follow used size

我正在使用 VisualVM 来分析一个 javafx 8 应用程序,该应用程序执行一些绘图并使用比我想要的多得多的内存。它似乎没有泄漏,但由于某种原因,我的总堆从未减少,即使我使用的堆随着我 select 不同文件的绘制而上下波动。所有的尖峰都是在我绘制一个新文件时出现的,然后在我退出该屏幕时下降,但总堆只是猛增并保持不变。这正常吗?

是的,这很正常。 JVM 从 OS 分配更多的堆内存并且不归还它,但实际使用情况可能会有所不同,即堆中当前未使用的部分可能会发生变化。

一个原因是从 OS 分配内存有点昂贵,而且一旦写入数据实际上可能会碎片化。垃圾收集可能会释放内存块,因此使用的大小会减少,但仍然使用的块可能会分布在整个堆内存中。

我不确定 JVM 实际上是如何详细处理的(事实上,不同的 JVM 可能会以不同的方式处理),但您可以查找在这种情况下使用的空闲列表、伙伴系统等。

有人可能会争辩说,JVM 可以 "defragment" 垃圾收集后的内存,然后释放多余的堆内存,但这会对性能造成很大影响,尤其是如果必须在 RAM 中移动大量数据时甚至 virtual/swap 内存。与许多计算问题一样,它是 space 和 cpu 用法之间的权衡。