答:如果我使用-Xmx100000m(〜100GB)执行一个巨大的仿真程序,我会看到使用的堆(〜30 GB)中出现一些峰值.峰值会增加堆大小,并减少其他程序可以使用的内存.我想将堆大小限制为在没有内存异常的情况下运行程序实际所需的大小.
B.如果我使用-Xmx10000(〜10GB)执行模拟程序,则可以限制使用的堆大小(〜7 GB).总堆大小也较小(当然).在VisualVM图形中显示的程序的第一阶段(大约16分钟)中,我并没有遇到内存异常的问题.
我很天真地希望,如果我将xmx从10GB(B)增加到100GB(A),则使用的堆将保持不变,并且Java仅会使用更多的内存以避免内存不足的异常.但是,行为似乎有所不同.我想Java可以通过这种方式来提高性能.
对于A中使用大量堆的一种解释可能是,如果xmx较大,则哈希映射的增长行为会有所不同? xmx对负载系数有影响吗?
在程序阶段,其中存在许多迷你尖峰(例如,参见12:06的B),而不是几个大尖峰(A),一些Java流被处理.用于流处理的内存分配是否自动适应xmx值? (仍然有一些内存可以用来减少B中12:06的迷你尖峰.)
如果不是,那么在A中使用更大堆的原因可能是什么?
我如何告诉Java尽可能将使用的堆保持较低(如B的曲线所示),但是如果发生内存不足异常(允许临时切换到A),则要占用更多的内存.是否可以通过调整某些垃圾回收属性来完成?
编辑
如以下答案所述,可以通过垃圾回收参数来更改配置文件.应用-Xmx100000m -XX:MaxGCPauseMillis = 1000可以使A中的配置文件适应更少的内存(已使用〜20 GB)和更多的时间(〜22 min).
解决方法:
I would like to limit the heap size to the size that is actually required to run the program without memory exceptions.
您实际上并不想这样做,因为这将使您的程序极其缓慢,因为仅提供与应用程序峰值占用量相等的数量就意味着,当应用程序接近最大值时,每一次分配都会触发垃圾回收.
I guess that Java works this way in order to improve performance.
确实.
JVM有几个目标,按降序排列:
>暂停时间(延迟)
>分配吞吐量
>足迹
如果要优先考虑其他目标,则必须放宽其他目标.
>设置-XX:MaxGCPauseMillis = 18446744073709551615,这是并行收集器的默认设置,但G1的默认设置为200ms.
> configure it to keep less breathing room
标签:memory-management,java,garbage-collection
来源: https://codeday.me/bug/20191118/2026159.html