A. 如果我使用-Xmx100000m(约100GB)运行一个大型的模拟程序,我会看到堆使用出现一些峰值(约30 GB)。这些峰值会增加堆大小并减少其他程序可以使用的内存。我想将堆大小限制在实际运行程序所需的大小,以避免内存异常。
B. 如果我使用-Xmx10000(约10GB)运行我的模拟程序,我能够限制堆使用大小(约7GB)。总堆大小也较小(当然)。在VisualVM图表中显示的程序第一阶段(约16分钟)中,我不会遇到内存异常。
我天真地认为,如果我将xmx从10GB(B)增加到100GB(A),那么使用的堆大小将保持大致相同,Java只会使用更多的内存以避免内存异常。但实际情况似乎不同。我猜测Java这样做是为了提高性能。
造成A中较大使用的堆的解释可能是,如果xmx更大,哈希映射的增长行为会有所不同? xmx是否会影响负载因子?
在许多小波峰存在的程序阶段(例如B在12:06),一些Java流被处理。流处理的内存分配是否会自动适应xmx值?(仍然有一些内存可以使用,以便在B的12:06处拥有更少的小尖峰)。
如果没有,那么A中较大的使用堆的原因可能是什么?
如何告诉Java尽可能保持低的使用堆(类似于B的曲线),但如果可能发生内存不足异常,则可以取更多的内存(允许暂时切换到A)。这可以通过调整某些垃圾回收属性来完成吗?
编辑
如下答案所述,垃圾回收参数可以改变配置文件。应用-Xmx100000m -XX:MaxGCPauseMillis = 1000可以将配置文件从A适应为占用更少的内存(约20 GB使用)和更多的时间(约22分钟)。