在 G1 中将 G1HeapWastePercent 设置为零的后果
Consequences of setting G1HeapWastePercent to zero in G1
美好的一天,我在生产中使用 G1(热点 JDK 11)并试图了解它是如何工作的。据我了解,G1 中的 Old GC 只会清理那些充满垃圾的区域,否则这些区域会被放入某个队列。
稍后触发混合 GC,它将使用 amount of Old generations/G1MixedGCCountTarget
个旧区域清理年轻区域。要扫描的旧区域由 G1MixedGCLiveThresholdPercent
确定,默认情况下为 65%,如果该区域的 65% 是垃圾,则它将被清理。
但是我不确定我是否理解G1HeapWastePercent
的意思。
来自官方文档
Sets the percentage of heap that you are willing to waste. The Java >HotSpot VM does not initiate the mixed garbage collection cycle when the >reclaimable percentage is less than the heap waste percentage. The default is 10 percent. This setting is not available in Java HotSpot VM, build 23.
假设区域包含 65% 的垃圾。 G1 开始将生命对象从 Young region 移动到单个充满垃圾的 Old region,一旦这个 region 只包含 10% 的垃圾,G1 就切换到另一个 old region 区域。如果我的假设是正确的,那么将 G1HeapWastePercent
设置为 0 将用生命对象完全填充该区域。这是正确的吗 ?如果时间延迟不是我的应用程序的优先级,我将 G1HeapWastePercent 设置为零会有任何好处吗?
首先,我想你可能误解了G1MixedGCLiveThresholdPercent
的作用(Jdk7默认值为65%,Jdk11默认值为85%)。
G1MixedGCLiveThresholdPercent
不是垃圾对象的space比例,而是活对象的space比例。如果一个region中的存活对象space超过85%(在jdk11中),那么该region将不会被select编入
collection set
(待回收区域合集)
其次,G1HeapWastePercent
(Jdk7默认为10%,Jdk11默认为5%
是触发Mixed GC和退出Mixed GC的条件。
当collection set
中的垃圾对象占堆分配总量的5%以上(在jdk11中)space,
将触发Mixed GC,退出Mixed GC的充分条件之一即
collection set
中的垃圾对象率低于5%。
因此,如果G1HeapWastePercent
设置为0%,只要回收集中有垃圾对象,就会触发Mixed GC。
那么退出Mixed GC的充分条件就会变成collection set
为空,
因为每次 Mixed GC 都会从 collection set
.
中移除回收的区域
最后想给大家讲解一下G1 GC的执行过程,让大家更好的理解整个过程。
G1 包含 3 个阶段,concurrent marking
、Only Young GC
和 Mixed GC
。大致流程如下:
- 在
Only Young GC
结束时会判断是否需要开始concurrent marking
concurrent marking
完成后,会计算每个region(老年代)的存活对象和垃圾对象占用的space。
- 然后生成
collection set
(待回收的old region集合),只有存活对象大小占region总大小超过G1MixedGCLiveThresholdPercent的old generation region才会进入collection set
.
- 之后,对
collection set
进行排序,最高的_gc_efficiency
排名第一
- 如果
collection set
的reclaimable_percent
超过G1HeapWastePercent
%,则Mixed GC
稍后触发。
Mixed GC
将 select 回收所有年轻区域和 old_region_length
旧区域。
- Mixed GC执行结束后,如果
reclaimable_percent
仍然超过G1HeapWastePercent
%,那么稍后会再次执行Mixed GC
。
我来解释一下下面提到的几个参数和概念:
G1MixedGCLiveThresholdPercent
- openjdk11中默认值为85,G1MixedGCLiveThresholdPercent
- 相关使用位置为mixed_gc_live_threshold_bytes,用于计算单个区域内物体存活率的阈值。超过这个门槛的地区将不会进入
collection set
.
_gc_efficiency
- 单个区域的回收价值
- _gc_efficiency =
the size of garbage objects in a single region
/ the time it takes to transfer this region
- 如果区域内垃圾对象越多,传送时间越短,_gc_efficiency会更高
G1HeapWastePercent
- openjdk11中默认值为5,G1HeapWastePercent
- 相关代码next_gc_should_be_mixed用于判断下一次GC是否为
Mixed GC
.
reclaimable_percent
- reclaimable_percent =
garbage object size
/ total space size
- 这里的垃圾对象是指
collection set
中垃圾对象的总大小
G1MixedGCCountTarget
- openjdk11中默认值为8,G1MixedGCCountTarget
- 表示一旦触发Mixed GC,期望执行8次Mixed GC。
G1OldCSetRegionThresholdPercent
- openjdk11中默认值为10,G1OldCSetRegionThresholdPercent
- 每次Mixed GC,selected old_region_length有一个最大值
- 最大值=
the number of allocated regions in heap
*10 / 100
old_region_length
- 这个值表示
collecion set
的Mixed GC
selectsold_region_length
个Old Regions要回收
- 这个值的下限是
min_old_cset_length
, and the upper limit is max_old_cset_length
min_old_cset_length
= the size of collection set / G1MixedGCCountTarget
.
max_old_cset_length
= the number of allocated regions in heap * G1OldCSetRegionThresholdPercent / 100
- 因为G1会严格控制每个
GC Pause Time
,所以最后的old_region_length受到gc停顿时间的约束。但是Mixed GC会将collecion set
中尽可能多的region放入old_region_length
,直到回收这些region的总时间接近预估的GC Pause Time
.
美好的一天,我在生产中使用 G1(热点 JDK 11)并试图了解它是如何工作的。据我了解,G1 中的 Old GC 只会清理那些充满垃圾的区域,否则这些区域会被放入某个队列。
稍后触发混合 GC,它将使用 amount of Old generations/G1MixedGCCountTarget
个旧区域清理年轻区域。要扫描的旧区域由 G1MixedGCLiveThresholdPercent
确定,默认情况下为 65%,如果该区域的 65% 是垃圾,则它将被清理。
但是我不确定我是否理解G1HeapWastePercent
的意思。
来自官方文档
Sets the percentage of heap that you are willing to waste. The Java >HotSpot VM does not initiate the mixed garbage collection cycle when the >reclaimable percentage is less than the heap waste percentage. The default is 10 percent. This setting is not available in Java HotSpot VM, build 23.
假设区域包含 65% 的垃圾。 G1 开始将生命对象从 Young region 移动到单个充满垃圾的 Old region,一旦这个 region 只包含 10% 的垃圾,G1 就切换到另一个 old region 区域。如果我的假设是正确的,那么将 G1HeapWastePercent
设置为 0 将用生命对象完全填充该区域。这是正确的吗 ?如果时间延迟不是我的应用程序的优先级,我将 G1HeapWastePercent 设置为零会有任何好处吗?
首先,我想你可能误解了G1MixedGCLiveThresholdPercent
的作用(Jdk7默认值为65%,Jdk11默认值为85%)。
G1MixedGCLiveThresholdPercent
不是垃圾对象的space比例,而是活对象的space比例。如果一个region中的存活对象space超过85%(在jdk11中),那么该region将不会被select编入
collection set
(待回收区域合集)
其次,G1HeapWastePercent
(Jdk7默认为10%,Jdk11默认为5%
是触发Mixed GC和退出Mixed GC的条件。
当collection set
中的垃圾对象占堆分配总量的5%以上(在jdk11中)space,
将触发Mixed GC,退出Mixed GC的充分条件之一即
collection set
中的垃圾对象率低于5%。
因此,如果G1HeapWastePercent
设置为0%,只要回收集中有垃圾对象,就会触发Mixed GC。
那么退出Mixed GC的充分条件就会变成collection set
为空,
因为每次 Mixed GC 都会从 collection set
.
最后想给大家讲解一下G1 GC的执行过程,让大家更好的理解整个过程。
G1 包含 3 个阶段,concurrent marking
、Only Young GC
和 Mixed GC
。大致流程如下:
- 在
Only Young GC
结束时会判断是否需要开始concurrent marking
concurrent marking
完成后,会计算每个region(老年代)的存活对象和垃圾对象占用的space。- 然后生成
collection set
(待回收的old region集合),只有存活对象大小占region总大小超过G1MixedGCLiveThresholdPercent的old generation region才会进入collection set
. - 之后,对
collection set
进行排序,最高的_gc_efficiency
排名第一
- 然后生成
- 如果
collection set
的reclaimable_percent
超过G1HeapWastePercent
%,则Mixed GC
稍后触发。 Mixed GC
将 select 回收所有年轻区域和old_region_length
旧区域。- Mixed GC执行结束后,如果
reclaimable_percent
仍然超过G1HeapWastePercent
%,那么稍后会再次执行Mixed GC
。
- Mixed GC执行结束后,如果
我来解释一下下面提到的几个参数和概念:
G1MixedGCLiveThresholdPercent
- openjdk11中默认值为85,G1MixedGCLiveThresholdPercent
- 相关使用位置为mixed_gc_live_threshold_bytes,用于计算单个区域内物体存活率的阈值。超过这个门槛的地区将不会进入
collection set
.
_gc_efficiency
- 单个区域的回收价值
- _gc_efficiency =
the size of garbage objects in a single region
/the time it takes to transfer this region
- 如果区域内垃圾对象越多,传送时间越短,_gc_efficiency会更高
G1HeapWastePercent
- openjdk11中默认值为5,G1HeapWastePercent
- 相关代码next_gc_should_be_mixed用于判断下一次GC是否为
Mixed GC
.
reclaimable_percent
- reclaimable_percent =
garbage object size
/total space size
- 这里的垃圾对象是指
collection set
中垃圾对象的总大小
G1MixedGCCountTarget
- openjdk11中默认值为8,G1MixedGCCountTarget
- 表示一旦触发Mixed GC,期望执行8次Mixed GC。
G1OldCSetRegionThresholdPercent
- openjdk11中默认值为10,G1OldCSetRegionThresholdPercent
- 每次Mixed GC,selected old_region_length有一个最大值
- 最大值=
the number of allocated regions in heap
*10 / 100
old_region_length
- 这个值表示
collecion set
的Mixed GC
selectsold_region_length
个Old Regions要回收 - 这个值的下限是
min_old_cset_length
, and the upper limit ismax_old_cset_length
min_old_cset_length
=the size of collection set / G1MixedGCCountTarget
.max_old_cset_length
=the number of allocated regions in heap * G1OldCSetRegionThresholdPercent / 100
- 因为G1会严格控制每个
GC Pause Time
,所以最后的old_region_length受到gc停顿时间的约束。但是Mixed GC会将collecion set
中尽可能多的region放入old_region_length
,直到回收这些region的总时间接近预估的GC Pause Time
.