一、序言
目前企业级主流使用的Java版本是8,垃圾回收器支持手动修改为G1,G1垃圾回收器是Java 11的默认设置,因此G1垃圾回收器可以用很长时间,现阶段垃圾回收器优化意味着针对G1垃圾回收器优化。
为了简化讨论,下面假设针对4C/16G物理机器进行优化。
二、G1概览
(一)了解G1
1、最大堆大小
G1管理的最大堆大小为64G。每个Region的大小通过-XX:G1HeapRegionSize来设置,大小为1~32MB,默认最多可以有2048个Region,G1能管理的最大堆内存是32MB*2048=64G。
使用G1垃圾回收器最小堆内存应为1MB*2048=2GB,低于此值建议使用其它垃圾回收器。
2、Region大小
Region大小为1~32MB,具体取值有1MB、2MB、4MB、8MB、16MB、32MB,Region大小优化与大对象有关,当对象占用内存超过Region的一半时将被视为大对象。
被标记为大对象将不利于垃圾回收。
3、获取默认值
查看本地JVM特别是G1垃圾回收器当前的默认值。
java -XX:+PrintFlagsInitial >> ~/1.txt
(二)三种GC模式
G1垃圾回收器有两种垃圾回收模式,新生代回收和混合回收,特殊情况下会切换到Full GC。
1、新生代回收
新生代回收在最大停顿时间内,会处理所有Eden区的垃圾。具体操作是将Eden区所有存活的对象复制到Survivor区,同时清空Eden区。
新生代回收伴随着应用暂停,最长停顿时间不超过最大停顿时间,新生代回收尽管有暂停机制,考虑到并行回收的特性,回收逻辑相对简单,回收效率依然较高。一般而言,新生代回收实际耗时通常低于最大停顿时间。
新生代回收触发时机是新创建的对象在Eden区找不到足够的存储空间。
2、混合回收
混合回收伴随着新生代回收和老年代回收,在最大停顿时间范围内,会处理大部分Eden区的垃圾和一部分老年代垃圾。
老年代回收毫无疑问会伴随着应用暂停。混合回收操作比较复杂,相对新生代回收来说,单位时间回收的垃圾数要少,回收效率要低。一般而言,混合回收的实际耗时通常接近或者等于最大停顿时间。
混合回收触发时机是由参数InitiatingHeapOccupancyPercent控制,默认值为45,含义是老年代占用空间大小与堆的总大小比值超过此数便会触发混合回收。
默认值45%