堆参数对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调整参数。