简体   繁体   English

最大堆大小xmx如何影响Java中的内存分配/使用堆?

[英]How does maximum heap size xmx influence the memory allocation / used heap in Java?

A. If I execute a huge simulation program with -Xmx100000m (~100GB) I see some spikes in the used heap (~30 GB). 如果我用-Xmx100000m (~100GB)执行一个巨大的模拟程序,我会看到使用堆中的一些尖峰(~30 GB)。 That spikes increase the heap size and decreases the memory that can be used by other programs. 这种峰值会增加堆大小并减少其他程序可以使用的内存。 I would like to limit the heap size to the size that is actually required to run the program without memory exceptions. 我想将堆大小限制为在没有内存异常的情况下运行程序实际所需的大小。

在此输入图像描述

B. If I execute my simulation program with -Xmx10000 (~10GB) I am able to limit the used heap size (~ 7 GB). B.如果我用-Xmx10000 (~10GB)执行我的模拟程序,我可以限制使用的堆大小(~7 GB)。 The total heap size is less, too (of course). 总堆大小也是(当然)。 I do not get out of memory exceptions in the first phase of the program that is shown in the VisualVM figures (about 16 minutes). 我在VisualVM数据中显示的程序的第一阶段(约16分钟)内没有内存异常。

在此输入图像描述

I naively expected that if I increase xmx from 10GB (B) to 100GB (A) that the used heap would stay about the same and that Java only would use more memory in order to avoid out of memory exceptions. 我天真地期望,如果我将xmx从10GB(B)增加到100GB(A),那么使用的堆将保持大致相同,并且Java只会使用更多内存以避免内存不足异常。 However, the behavior seems to be different. 但是,行为似乎有所不同。 I guess that Java works this way in order to improve performance. 我想Java是以这种方式工作以提高性能。

An explanation for the large used heap in A might be that the growth behavior of hash maps is different if xmx is larger? 对A中大量使用堆的解释可能是,如果xmx较大,则哈希映射的增长行为会有所不同? Does xmx have an effect on the load factor? xmx会对负载系数产生影响吗?

In the phase of the program where a lot of mini spikes exist (see for example B at 12:06) instead of a few large ones (A) some java streams are processed. 在存在大量迷你尖峰的程序阶段(参见例如B在12:06)而不是几个大的尖峰(A)处理一些java流。 Does the memory allocation for stream processing automatically adapt with the xmx value? 流处理的内存分配是否自动适应xmx值? (There is still some memory left that could be used to have less mini spikes at 12:06 in B.) (还剩下一些记忆,可以用来在B的12:06减少迷你尖峰)

If not, what might be the reasons for the larger used heap in A? 如果没有,A中使用较大堆的原因可能是什么?

How can I tell Java to keep the used heap low if possible (like in the curves for B) but to take more memory if an out of memory exception could occur (allow to temporarily switch to A). 如果可能的话,我如何告诉Java保持使用的堆低(如B的曲线),但如果发生内存不足异常(允许暂时切换到A)则需要占用更多内存。 Could this be done by tuning some garbage collection properties? 这可以通过调整一些垃圾收集属性来完成吗?

Edit 编辑

As stated by the answer below, the profile can be altered by garbage collection parameters. 如下面的答案所述,可以通过垃圾收集参数更改配置文件。 Applying -Xmx100000m -XX:MaxGCPauseMillis=1000 adapts the profile from A to consume less memory (~ 20 GB used) and more time (~ 22 min). 应用-Xmx100000m -XX:MaxGCPauseMillis = 1000从A调整配置文件以消耗更少的内存(使用约20 GB)和更多时间(约22分钟)。

在此输入图像描述

I would like to limit the heap size to the size that is actually required to run the program without memory exceptions. 我想将堆大小限制为在没有内存异常的情况下运行程序实际所需的大小。

You do not actually want to do that because it would make your program extremely slow because only providing the amount equivalent to the application peak footprint means that every single allocation would trigger a garbage collection while the application is near the maximum. 您实际上并不想这样做,因为它会使您的程序极其缓慢,因为只提供与应用程序峰值占用量相当的数量意味着每个分配都会在应用程序接近最大值时触发垃圾回收。

I guess that Java works this way in order to improve performance. 我想Java是以这种方式工作以提高性能。

Indeed. 确实。

The JVM has several goals, in descending order: JVM有几个目标,按降序排列:

  • pause times (latency) 暂停时间(延迟)
  • allocation throughput 分配吞吐量
  • footprint 脚印

If you want to prioritize footprint over other goals you have to relax the other ones. 如果你想将足迹优先于其他目标,你必须放松其他目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM