我有一个程序,它基本上从磁盘读取许多文件(混合PDF通常低于10 MB + XML大小为Kb),并一次一个地上传到遗留系统。我让它在周末时在visualvm下运行,今天早上我回到了一个图表,显示在程序运行的小时内堆使用率相当不均匀。我期待随着时间的推移大量使用堆。
我正在寻找解释。这是在Ubuntu 17.04(桌面,而不是服务器)下的64位Oracle JVM,在4核i5-2400上没有32 GB RAM(没有超线程)。该程序基本上是单线程的,利用了大约50%的核心并花费了预期的时间来运行。
据我所知,如果内存没有被完全使用,它会随着时间的推移而被释放。我不明白随着时间的推移,使用量会下降,因为负载应该分布均匀。我是否看到CPU限制的结果,因为系统处于空闲状态?是否有一些JVM优化正在进行中?
答案 0 :(得分:2)
实际GC日志会更有帮助,但可能只是GC启发式调整他们关于年轻和旧堆大小的决定,以满足吞吐量和暂停时间目标。
只要你不对JVM设置限制,它就会愉快地使用比最低限度更少的内存来保持程序运行。如果没有,您会遇到非常频繁且效率低下的GC。换句话说,堆大小= n *活动对象集大小与 n > 1.根据所使用的收集器,可用内存可能没有上限,因为ParallelGC默认MaxHeapFreeRatio
为100而G1使用70。
启发式方法远非完美,它们可以在某些边缘情况下将自己绘制成一个角落,或者在不同的平衡点之间不必要地波动。但图表本身并不表示存在问题。