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

大多数网上的地方,我得到关于堆参数的信息

-Xms set initial Java heap size -Xmx set maximum Java heap size

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

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

在与我的同事讨论时 ,默认情况下,GC将触发60%的Xms值。 那是对的吗 ? 如果是,是次要GC还是完全GC依赖于Xms值?

关于Xms的更新: –在读取JVM堆参数之后这似乎是真的,但默认情况下值是60%并且是依赖于Xms值的次要GC还是完整GC?

-Xmx: –我的理解是提到-Xmx 2048M,java进程实际上是要从OS中保留2048M内存,因为另一个进程无法给它的共享。如果java进程无论如何都需要2048M以上的内存,那么内存不足将被抛出。

另外我认为在-Xmx的值上有一些Full GC触发器的关系。 因为我观察到的是当内存达到Xmx的70%时,Full GC发生在jconsole中。 那是对的吗?

配置: –我使用的是linux box(64位JVM 8)。 默认GC即并行GC

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

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

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

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

次要GC所有新对象都在Eden空间中分配(除了直接存储在Old代中的大型对象)。 当Eden空间变满时,将触发轻微GC。 存在多个次要GC的对象将升级为旧生成(默认为15个周期,可以使用JVM参数更改:MaxTenuringThreshold)。

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

并行收集器目标

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

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

更多细节在这里

Xms到Xmx
在启动期间,JVM会创建大小为Xms的堆,但保留额外的空间(Xmx)以便以后能够增长。 该保留空间称为虚拟空间。 请注意,它只是保留空间而不是提交。

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

  • MinHeapFreeRatio(默认值:40%) :一旦空闲堆空间低于40%,就会触发Full GC,堆大小增加20%。 因此,堆大小可以继续增长,直到达到Xmx。
  • MaxHeapFreeRatio(默认值:70%) :另一方面,堆空闲空间超过70%,然后堆积大小在每个GC期间递增减少5%,直到达到Xms。

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

PS :JVM GC是一个引人入胜的主题,我建议您阅读这篇优秀的文章,以便深入了解。 可以在此处找到所有JVM调整参数。