提问者:小点点

堆参数对GC/性能的影响?


在网上的大部分地方,我得到了下面关于堆参数的信息

-Xms

当我提到-Xms 512M -Xmx 2048M参数时,这是我的理解/问题,

-Xms:-我的理解是,如果我的java进程实际上只需要200M,提到-Xms512M,java进程仍然只分配200M(实际需要的内存)而不是500M。但是如果我已经知道我的应用程序将在启动时占用512M内存,那么指定小于将对性能产生影响,因为无论如何堆块需要调整大小,这是昂贵的操作。

根据与我同事的讨论,默认情况下GC将触发60%的Xms值。这是正确的吗?如果是,是依赖于Xms值的小GC还是全GC?

Xms更新:-阅读JVM堆参数后似乎是这样,但默认情况下值为60%,它是依赖于Xms值的次要还是完整GC?

-Xmx:- 我的理解是提到 -Xmx 2048M ,java进程实际上将从操作系统保留2048M内存供其使用,因此无法为另一个进程提供其份额。如果Java进程需要超过2048M的内存,那么内存不足将被抛出。

此外,我相信Full GC触发器与-Xmx的值之间存在某种关系。因为我观察到的是,当内存接近Xmx的70%时,jconsole中会发生Full GC。这是正确的吗?

配置:-我正在使用linux box(64位JVM 8)。默认GC即并行GC


共1个答案

匿名用户

GC不是仅基于Xms或Xmx值触发的。

堆=新-旧代
堆大小(最初设置为Xms)分为两代-新(又名年轻)和旧(又名有期)。默认情况下,新一代是总堆大小的1/3,而旧一代是堆大小的2/3。这可以通过使用名为NewRatio的JVM参数进行调整。其默认值为2。

年轻一代在伊甸园和2个幸存者空间中进一步划分。这3个空间的默认比例为:3/4、1/8、1/8。

旁注:这是关于并行 GC 收集器的。对于 G1 - 新的 GC 算法以不同的方式划分堆空间。

次要GC所有新对象都分配在Eden空间中(除了直接存储在旧一代中的大型对象)。当伊甸园空间变满时,会触发次要GC。在多个次要GC中幸存的对象将升级到旧一代(默认为15个周期,可以使用JVM参数MaxTenuringThreshold进行更改)。

主GC与并发收集器不同,并发收集器基于已用空间(默认为70%)触发主GC,并行收集器基于下面提到的3个目标计算阈值。

并行收集器目标

  • 最大GC暂停时间-执行GC花费的最大时间
  • 吞吐量-在GC与应用程序中花费的时间百分比。默认值(1%)
  • 占用空间-最大堆大小(Xmx)

因此,默认情况下,并行收集器尝试在垃圾回收中花费最多 1% 的应用程序总运行时间。

此处提供更多详细信息

Xms到Xmx<br>在启动过程中,JVM会创建Xms大小的堆,但会保留额外的空间(Xmx)以便以后能够增长。这个保留的空间被称为虚拟空间。请注意,它只是保留了空间,并没有promise。

2 个参数决定堆大小何时在 Xms 和 Xmx 之间增长(或缩小)。

  • MinHeapFreeRatio(默认值:40%):一旦可用堆空间降至40%以下,就会触发Full GC,堆大小会增长20%。因此,堆大小可以不断增长,直到达到Xmx。
  • MaxHeapFreeRatio(默认值:70%):另一方面,堆空闲空间超过70%,然后堆大小在每个GC期间增量减少5%,直到达到Xms。

这些参数可以在启动期间设置。阅读更多关于它的信息 这里 和 这里.

PS: JVM GC是一个迷人的话题,我推荐阅读这篇优秀的文章来深入了解。所有JVM调优参数都可以在这里找到。