代码先锋网 代码片段及技术文章聚合

CMS的CMSInitiatingOccupancyFraction默认值是多少?又是如何使用的?

经常看到有人谈到CMSInitiatingOccupancyFraction,但有的人说默认值是68,有的人又说是默认92,还有人干脆丢出了一个计算公式让你自己去算。

众口不一,这鬼知道到底哪个说的对。

后面就自己在openjdk里面找了下CMS的相关实现,最终找到了用来确定CMSInitiatingOccupancyFraction的这个方法:
ConcurrentMarkSweepGeneration.cpp:

void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, uintx tr) {
  assert(io <= 100 && tr <= 100, "Check the arguments");
  if (io >= 0) {
    _initiating_occupancy = (double)io / 100.0;
  } else {
    _initiating_occupancy = ((100 - MinHeapFreeRatio) +
                             (double)(tr * MinHeapFreeRatio) / 100.0)
                            / 100.0;
  }
}

其中两个参数,io就是CMSInitiatingOccupancyFraction的值,如果你没设置过就是虚拟机自己的默认值,默认-1,可以用指令来查看:

java -XX:+PrintFlagsFinal -version |grep CMSInitiatingOccupancyFraction

tr就是JVM启动参数CMSTriggerRatio的值,没手动设置过的话也同样也可以用指令来查看默认值:

java -XX:+PrintFlagsFinal -version |grep CMSTriggerRatio

这个方法的逻辑很简单,就是CMSInitiatingOccupancyFraction大于等于0就走上面分支,否则走下面分支。

如果你自己设置过-XX:CMSInitiatingOccupancyFraction=70,那么最终_initiating_occupancy=70%。在你设置了-XX:+UseCMSInitiatingOccupancyOnly的情况下,老年代内存使用率一旦超过70%就会执行CMS GC了。

如果你没设置过CMSInitiatingOccupancyFraction,默认值-1就走下面分支了。在该分支下还用到一个启动参数:MinHeapFreeRatio。emmm,怎么看值是啥不用我多说吧:

  java -XX:+PrintFlagsFinal -version |grep MinHeapFreeRatio

其实省事点也可以一次查看这三个启动参数的值:

java -XX:+PrintFlagsFinal -version |grep -E "CMSInitiatingOccupancyFraction|MinHeapFreeRatio|CMSTriggerRatio"

我分别在JDK1.7(1.7.0_67-b01)和JDK1.8(1.8.0_171)下看了这三个参数的值:
CMSInitiatingOccupancyFraction和CMSTriggerRatio都是-1和80。
但是MinHeapFreeRatio在JDK1.7是0,所以根据公式计算_initiating_occupancy最终得到的值是100%。
而MinHeapFreeRatio在JDK1.8是40,根据公式_initiating_occupancy计算得到的值是92%(68%的可能是其他版本计算得到的值了~)

大家也可以自己试试,看看自己JVM版本中MinHeapFreeRatio值是多少,最终计算得到的_initiating_occupancy又是多少。

最后来总结一下吧:
1、CMSInitiatingOccupancyFraction默认值是-1,并不是许多人说的68、92之类的。

2、CMSInitiatingOccupancyFraction是用来计算老年代最大使用率(_initiating_occupancy)的。大于等于0则直接取百分号,小于0则根据公式来计算。这个_initiating_occupancy需要配合-XX:+UseCMSInitiatingOccupancyOnly来使用。

3、不同版本最终得到的_initiating_occupancy不同,归根结底应该是不同版本下的MinHeapFreeRatio值不同。

版权声明:本文为insomsia原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/insomsia/article/details/91802923

智能推荐

SQLserver 如何删除设置了默认值的列

SQLserver 删除含默认值的列出现以下错误: 消息 5074,级别 16,状态 1,第 79 行 对象’DF__student__入学时间__3F466844’ 依赖于 列’入学时间’。 消息 4922,级别 16,状态 9,第 79 行 由于一个或多个对象访问此 列,ALTER TABLE DROP COLUMN 入学时间 失败。 接下来介绍...

Controller如何设置接受参数的默认值?

@RequestParam代表的是请求参数注解:   1.value:代表我们传递过来的参数名称时kkk,我们使用的时pageNo来接收。只要浏览器传递过来的参数时pageNo,我们可以不写value这个属性的。   2.required=false,代表的这个参数可以不传。   3.defaultValue:代表我们给这个参数设置的默认值。   4.int 代表参数的类型。...

解构默认值+参数默认值 的区别

上面的例子中 函数参数默认值的 { y: 10 } 值是一个对象,而不是 解构默认值。因此,它只在第二参数没有传入,或者传入 undefined 的时候才会生效。 传入了第二个参数 ({}),所以没有使用默认值 { y: 10 },而是在传入的空对象值 {} 上进行 { y } 解构。   { x = 10 } 是解构默认值,传入undefined,使用{}进行解构,传入{},...

Spring的PropertyPlaceholderConfigurer强制使用默认值的坑

1.问题 dubbo client配置: dubbo.properties: dubbo配置时,预期效果:url="${dubbo.url.channel:#{null}}" 会先读取配置文件dubbo.url.channel的值如果有值则读取,若配置文件无该值则用默认值null。 但是事实上无论dubbo.properties配置文件是否有dubbo.url.channel。...

@Value默认值的使用方法

上面的两行代码表示,从application.properties或者yml文件中读取address.host1的值赋给host1属性,但有些情况我们需要一个默认值,我们可以用下面的方法来实现 通过在address.host1后面加冒号,后面即可设置默认值,此处我的默认值为127.0.0.1。 又或者我们想让host1属性的默认值为空字符串(即“”) 这样host1的默认值...

猜你喜欢

使用js代码修改input的默认值

内容:使用js代码来对input设置的默认值进行修改,点击按钮修改input的默认值 代码: 效果图:    ...

mysql中int类型的字段没赋默认值为空时如何使用查询条件

问题: 当int类型的字段没赋默认值为0,当插入数据为空时如何使用查询条件吧为null的数据查出来 错误: select * from table where a = null ? 把这些值都批量赋0后修改字段的默认值设为0,当下次再查询是判断a = 0即可 update table set a = 0 where isNull(a);...

mysqladmin查看variable的默认值

mysqld命令给出的信息: 查看...