《JVM G1源码分析和调优》 —2.2 G1停顿预测模型

举报
华章计算机 发表于 2019/12/20 13:07:02 2019/12/20
【摘要】 本节书摘来自华章计算机《JVM G1源码分析和调优》 一书中第2章,第2.2节,作者是彭成寒。

2.2 G1停顿预测模型

G1是一个响应时间优先的GC算法,用户可以设定整个GC过程的期望停顿时间,由参数MaxGCPauseMillis控制,默认值200ms。不过它不是硬性条件,只是期望值,G1会努力在这个目标停顿时间内完成垃圾回收的工作,但是它不能保证,即也可能完不成(比如我们设置了太小的停顿时间,新生代太大等)。

那么G1怎么满足用户的期望呢?就需要停顿预测模型了。G1根据这个模型统计计算出来的历史数据来预测本次收集需要选择的堆分区数量(即选择收集哪些内存空间),从而尽量满足用户设定的目标停顿时间。如使用过去10次垃圾回收的时间和回收空间的关系,根据目前垃圾回收的目标停顿时间来预测可以收集多少的内存空间。比如最简单的办法是使用算术平均值建立一个线性关系来预测。如过去10次一共收集了10GB的内存,花费了1s,那么在200ms的停顿时间要求下,最多可以收集2GB的内存空间。G1的预测逻辑是基于衰减平均值和衰减标准差。

衰减平均(Decaying Average)是一种简单的数学方法,用来计算一个数列的平均值,核心是给近期的数据更高的权重,即强调近期数据对结果的影响。衰减平均计算公式如下所示:

 image.png

式中α为历史数据权值,1-α为最近一次数据权值。即α越小,最新的数据对结果影响越大,最近一次的数据对结果影响最大。不难看出,其实传统的平均就是α取值为(n-1) /n的情况。

同理,衰减方差的定义如下:

 image.png

停顿预测模型是以衰减标准差为理论基础实现的,代码如下所示:

hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp

 

double get_new_prediction(TruncatedSeq* seq) {

  return MAX2(seq->davg() + sigma() * seq->dsd(),

              seq->davg() * confidence_factor(seq->num()));

}

在这个预测计算公式中:

davg表示衰减均值。

sigma()返回一个系数,来自G1ConfidencePercent(默认值为50,sigma为0.5)的

配置,表示信赖度。

dsd表示衰减标准偏差。

confidence_factor表示可信度相关系数,confidence_factor当样本数据不足时(小于5个)取一个大于1的值,并且样本数据越少该值越大。当样本数据大于5时confidence_factor取值为1。这是为了弥补样本数据不足,起到补偿作用。

方法的参数TruncateSeq,顾名思义,是一个截断的序列,它只跟踪序列中最新的n个元素。在G1 GC过程中,每个可测量的步骤花费的时间都会记录到TruncateSeq

(继承了AbsSeq)中,用来计算衰减均值、衰减变量、衰减标准偏差等,代码如下所示:

hotspot/src/share/vm/utilities/numberSeq.cpp

 

void AbsSeq::add(double val) {

  if (_num == 0) {

    // 初始时,还没有历史数据,davg就是当前参数,dvar设置为0

    _davg = val;

    _dvariance = 0.0;

  } else {

    _davg = (1.0 - _alpha) * val + _alpha * _davg;

    double diff = val - _davg;

    _dvariance = (1.0 - _alpha) * diff * diff + _alpha * _dvariance;

  }

}

这个add方法就是上面两个衰减公式的实现代码。其中_davg为衰减均值,

_dvariance为衰减方差,_alpha默认值为0.7。G1的软实时停顿就是通过这样的预测模型来实现的。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。