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

时间:2016-09-23 03:50:23

标签: java memory-management garbage-collection heap

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

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

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

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

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

Xms更新:  在阅读JVM heap parameters之后,这似乎是正确的,但默认情况下值是60%,并且是依赖于Xms值的次要GC还是完整GC?

-Xmx: - 我的理解是提到-Xmx 2048M,java进程实际上是要从操作系统中保留2048M内存供其使用,因为另一个进程无法获得其共享。如果无论如何需要超过2048M内存的java进程,然后会抛出内存不足。

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

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

1 个答案:

答案 0 :(得分:3)

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

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

Young Generation进一步划分为Eden和2个Survivor空间。这3个空格的默认比例为:3 / 4,1 / 8,1 / 8。

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

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

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

并行收集者目标

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

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

更多详情here

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

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

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

可以在启动期间设置这些参数。详细了解herehere

PS :JVM GC是一个引人入胜的主题,我建议您阅读此excellent article以深入了解。可以找到所有JVM调整参数here