【发布时间】:2016-09-15 10:27:07
【问题描述】:
A. 如果我使用 -Xmx100000m (~100GB) 执行一个大型模拟程序,我会看到已用堆中的一些峰值 (~30 GB)。峰值会增加堆大小并减少其他程序可以使用的内存。我想将堆大小限制为在没有内存异常的情况下运行程序实际需要的大小。
B. 如果我使用 -Xmx10000 (~10GB) 执行我的模拟程序,我可以限制使用的堆大小(~ 7 GB)。总堆大小也更小(当然)。在 VisualVM 图中显示的程序的第一阶段(大约 16 分钟),我没有出现内存不足异常。
我天真地期望,如果我将 xmlx 从 10GB (B) 增加到 100GB (A),使用的堆将保持大致相同,并且 Java 只会使用更多内存以避免内存不足异常。但是,行为似乎有所不同。我猜想 Java 以这种方式工作是为了提高性能。
对于 A 中使用的大堆的解释可能是,如果 xmx 更大,哈希映射的增长行为会有所不同? xmx 对负载系数有影响吗?
在存在大量小尖峰的程序阶段(例如,参见 12:06 的 B)而不是少数大尖峰 (A),处理了一些 java 流。流处理的内存分配是否会自动适应 xmlx 值? (还有一些内存可以用来减少 B 中 12:06 的小尖峰。)
如果不是,A 中使用的堆较大的原因可能是什么?
如果可能的话,我如何告诉 Java 将已用堆保持在较低水平(如 B 的曲线中),但如果可能发生内存不足异常(允许临时切换到 A),则占用更多内存。这可以通过调整一些垃圾收集属性来完成吗?
编辑
正如下面的答案所述,配置文件可以通过垃圾收集参数进行更改。应用 -Xmx100000m -XX:MaxGCPauseMillis=1000 会调整 A 中的配置文件以消耗更少的内存(大约使用了 20 GB)和更多的时间(大约 22 分钟)。
【问题讨论】:
-
我认为这与垃圾收集算法有关。每当 GC 发现有足够的空间可用时,它就不会释放堆空间(在 A 的情况下)。但是当 GC 发现空间不足时,它会执行垃圾收集程序并定期和短时间释放空间(在案例 B 中)。
标签: java memory-management garbage-collection