文档章节

-XX:MaxTenuringThreshold

小胖子编程
 小胖子编程
发布于 2017/08/30 22:52
字数 1367
阅读 7
收藏 0
点赞 0
评论 0

用法: -XX:MaxTenuringThreshold=3 该参数主要是控制新生代需要经历多少次GC晋升到老年代中的最大阈值。在JVM中用4个bit存储(放在对象头中),所以其最大值是15。 但并非意味着,对象必须要经历15次YGC才会晋升到老年代中。例如,当survivor区空间不够时,便会提前进入到老年代中,但这个次数一定不大于设置的最大阈值。

那么JVM到底是如何来计算S区对象晋升到Old区的呢? 首先介绍另一个重要的JVM参数: -XX:TargetSurvivorRatio:一个计算期望s区存活大小(Desired survivor size)的参数。默认值为50,即50%。 当一个S区中所有的age对象的大小如果大于等于Desired survivor size,则重新计算threshold,以age和MaxTenuringThreshold两者的最小值为准。

以一个Demo为例:

//-Xmx200M -Xmn50m -XX:TargetSurvivorRatio=60 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=3
//最小堆为50M,默认SurvivorRatio为8,那么可以知道Eden区为40M,S0和S1为5M
public class App {
  public static void main(String[] args) throws InterruptedException {

        // main方法作为主线程,变量不会被回收
        byte[] byte1 = new byte[1 * 1024 * 1024];
        byte[] byte2 = new byte[1 * 1024 * 1024];

        YGC(40);
        Thread.sleep(3000);

        YGC(40);
        Thread.sleep(3000);

        YGC(40);
        Thread.sleep(3000);

        // 这次再ygc时, 由于byte1和byte2的年龄经过3次ygc后已经达到3(-XX:MaxTenuringThreshold=3), 所以会晋升到old
        YGC(40);
        // ygc后, s0(from)/s1(to)的空间为0
        Thread.sleep(3000);


        // 达到TargetSurvivorRatio这个比例指定的值,即 5M(S区)*60%(TargetSurvivorRatio)=3M(Desired survivor size)
        byte[] byte4 = new byte[1 * 1024 * 1024];
        byte[] byte5 = new byte[1 * 1024 * 1024];
        byte[] byte6 = new byte[1 * 1024 * 1024];

        // 这次ygc时, 由于s区已经占用达到了60%(-XX:TargetSurvivorRatio=60),
        // 所以会重新计算对象晋升的min(age, MaxTenuringThreshold) = 1
        YGC(40);
        Thread.sleep(3000);

        // 由于前一次ygc时算出age=1, 所以这一次再ygc时, byte4, byte5, byte6就要晋升到Old,
        // 而不需要等MaxTenuringThreshold这么多次, 此次ygc后, s0(from)/s1(to)的空间再次为0, 对象全部晋升到old
        YGC(40);
        Thread.sleep(3000);

        System.out.println("GC end!");
    }

    //塞满Eden区,局部变量会被回收,作为触发GC的小工具
    private static void YGC(int edenSize){
        for (int i = 0 ; i < edenSize ; i ++) {
            byte[] byte1m = new byte[1 * 1024 * 1024];
        }
    }

}

可以看到结果

//第一次YGC
2017-07-22T17:43:50.615-0800: [GC (Allocation Failure) 2017-07-22T17:43:50.615-0800: [ParNew: 39936K->2812K(46080K), 0.0126581 secs] 39936K->2812K(125952K), 0.0127387 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]  
//第二次YGC
2017-07-22T17:43:53.653-0800: [GC (Allocation Failure) 2017-07-22T17:43:53.653-0800: [ParNew: 43542K->2805K(46080K), 0.0144079 secs] 43542K->2805K(125952K), 0.0144607 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
//第三次YGC
2017-07-22T17:43:56.679-0800: [GC (Allocation Failure) 2017-07-22T17:43:56.679-0800: [ParNew: 43329K->2877K(46080K), 0.0010447 secs] 43329K->2877K(125952K), 0.0010784 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
//三次YGC后,此时age达到MaxTenuringThreshold阈值3,再次YGC时,会晋升到Old区,可以看到此时新生代空间为0
2017-07-22T17:43:59.691-0800: [GC (Allocation Failure) 2017-07-22T17:43:59.691-0800: [ParNew: 43604K->0K(46080K), 0.0065182 secs] 43604K->2675K(125952K), 0.0065664 secs] [Times: user=0.01 sys=0.01, real=0.00 secs] 
//分配3M不回收的对象,经历一次YGC,此时age=1
2017-07-22T17:44:02.708-0800: [GC (Allocation Failure) 2017-07-22T17:44:02.708-0800: [ParNew: 40731K->3072K(46080K), 0.0050035 secs] 43406K->5747K(125952K), 0.0050444 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
//此时可以看到,3M的对象也被晋升到了Old区,这可以证明,如果只靠MaxTenuringThreshold来决定多少次YGC才晋升到Old区的话,此时age=1,并没有达到阈值。
//因为此时3m达到TargetSurvivorRatio=60(5M*60=3m)的要求,那么前一次YGC,会重新计算对象晋升的threshold=min(age, MaxTenuringThreshold) = min(1,3) = 1次,所以此时晋升到了Old区
2017-07-22T17:44:05.722-0800: [GC (Allocation Failure) 2017-07-22T17:44:05.722-0800: [ParNew: 43806K->0K(46080K), 0.0060735 secs] 46481K->5747K(125952K), 0.0061215 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
GC end!
Heap
 par new generation   total 46080K, used 18003K [0x00000007b3800000, 0x00000007b6a00000, 0x00000007b6a00000)
  eden space 40960K,  43% used [0x00000007b3800000, 0x00000007b4994d88, 0x00000007b6000000)
  from space 5120K,   0% used [0x00000007b6000000, 0x00000007b6000000, 0x00000007b6500000)
  to   space 5120K,   0% used [0x00000007b6500000, 0x00000007b6500000, 0x00000007b6a00000)
 concurrent mark-sweep generation total 79872K, used 5747K [0x00000007b6a00000, 0x00000007bb800000, 0x00000007c0000000)
 Metaspace       used 3267K, capacity 4494K, committed 4864K, reserved 1056768K
  class space    used 354K, capacity 386K, committed 512K, reserved 1048576K

另外你可以在JVM启动参数中加上-XX:+PrintTenuringDistribution,该参数可以输出age的额外信息。

2017-07-22T18:07:51.401-0800: [GC (Allocation Failure) 2017-07-22T18:07:51.401-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age   1:    2854440 bytes,    2854440 total
: 39936K->2819K(46080K), 0.0136187 secs] 39936K->2819K(125952K), 0.0138705 secs] [Times: user=0.01 sys=0.01, real=0.01 secs] 
2017-07-22T18:07:54.452-0800: [GC (Allocation Failure) 2017-07-22T18:07:54.452-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age   2:    2682504 bytes,    2682504 total
: 43549K->2918K(46080K), 0.0172463 secs] 43549K->2918K(125952K), 0.0173506 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 
2017-07-22T18:07:57.484-0800: [GC (Allocation Failure) 2017-07-22T18:07:57.484-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age   3:    2680152 bytes,    2680152 total
: 43442K->2723K(46080K), 0.0115410 secs] 43442K->2723K(125952K), 0.0116179 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
2017-07-22T18:08:00.511-0800: [GC (Allocation Failure) 2017-07-22T18:08:00.511-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
: 43449K->0K(46080K), 0.0226608 secs] 43449K->2673K(125952K), 0.0228187 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
2017-07-22T18:08:03.547-0800: [GC (Allocation Failure) 2017-07-22T18:08:03.547-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 1 (max 3)
- age   1:    3145776 bytes,    3145776 total
: 40731K->3072K(46080K), 0.0055686 secs] 43404K->5745K(125952K), 0.0056352 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2017-07-22T18:08:06.572-0800: [GC (Allocation Failure) 2017-07-22T18:08:06.572-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
: 43806K->0K(46080K), 0.0068945 secs] 46479K->5745K(125952K), 0.0070480 secs] [Times: user=0.00 sys=0.01, real=0.00 secs] 
GC end!
Heap
 par new generation   total 46080K, used 18003K [0x00000007b3800000, 0x00000007b6a00000, 0x00000007b6a00000)
  eden space 40960K,  43% used [0x00000007b3800000, 0x00000007b4994d88, 0x00000007b6000000)
  from space 5120K,   0% used [0x00000007b6000000, 0x00000007b6000000, 0x00000007b6500000)
  to   space 5120K,   0% used [0x00000007b6500000, 0x00000007b6500000, 0x00000007b6a00000)
 concurrent mark-sweep generation total 79872K, used 5745K [0x00000007b6a00000, 0x00000007bb800000, 0x00000007c0000000)
 Metaspace       used 3273K, capacity 4494K, committed 4864K, reserved 1056768K
  class space    used 354K, capacity 386K, committed 512K, reserved 1048576K

© 著作权归作者所有

共有 人打赏支持
小胖子编程
粉丝 1
博文 9
码字总数 9126
作品 0
绍兴
新生代串行收集器对内存分配及回收的影响

通常情况下,对象在eden中分配。当eden无法分配时,触发一次Minor GC。 public class YoungGenGc{ VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 }......

忆瑶
2013/01/17
0
0
tomcat 高流量调优

java 环境配置:export JAVA_OPTS="-server -Xms8g -Xmx8g -Xss128k -XX:ParallelGCThreads=20-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8-XX:TargetSurvivorRatio=90 -......

千惊万喜
2016/12/09
26
0
zabbix一直报警,提示Scavenge回收时间超过MarkSweep,请问这个问题严重吗?如果严重,需要怎么解决?

GC配置的是通用的CMS。 JAVAOPTS="$JAVAOPTS -Xms2048m -Xmx2560m -XX:MaxPermSize=2048m" JVMOPTS="$JVMOPTS -XX:+UseParNewGC" JVMOPTS="$JVMOPTS -XX:+UseConcMarkSweepGC" JVMOPTS="$JV......

月之静谧
2016/01/14
410
0
windows 伪分布 solr索引数据 失败

windows 为分布 solr索引,开始是索引成功,过一段时间就 失败 ,日志提示: Connection to http://192.168.1.34:8081 refused 如果别的条件都正常,很有可能是部署solr的tomcat内存问题,我...

小叮当_加V
2016/09/29
12
0
JVM参数大全

-XX:PretenureSizeThreshold: 大于这个设置值的对象直接在老年代分配避免在Eden区及两个Survivor区之间发生大量的内存复制(只针对Serial和ParNew) -XX:MaxTenuringThreshold: 对象年龄计...

清风傲剑
2016/06/07
15
0
与垃圾回收有关的JVM参数

-Xms / -Xmx — 堆的初始大小 / 堆的最大大小 -Xmn — 堆中年轻代的大小 -XX:-DisableExplicitGC — 让System.gc()不产生任何作用 -XX:+PrintGCDetails — 打印GC的细节 -XX:+PrintGCDateSt...

蜡笔小小小新
2016/08/09
28
0
与垃圾回收相关的JVM参数

与垃圾回收相关的JVM参数: -Xms / -Xmx — 堆的初始大小 / 堆的最大大小 -Xmn — 堆中年轻代的大小 -XX:-DisableExplicitGC — 让System.gc()不产生任何作用 -XX:+PrintGCDetails — 打印G...

LYQ1990
2016/05/06
13
0
jvm参数设置

JAVAOPTS="-Xms2048m -Xmx2048m -Xmn768m -Xss512K -XX:PermSize=96m -XX:MaxPermSize=96m -XX:SurvivorRatio=8 -XX:InitialTenuringThreshold=8 -XX:MaxTenuringThreshold=8 -XX:ParallelGC......

星逝流
2016/01/04
48
0
java jvm GC 各个区内存参数设置

1: heap size a: -Xmx 指定jvm的最大heap大小,如:-Xmx2g b: -Xms 指定jvm的最小heap大小,如:-Xms1g c: -Xmn 指定jvm中New Generation的大小,如:-Xmn256m d: -XX:PermSize 指定jvm中Perm Gene......

枯藤KT
2016/02/17
43
1
windows tomcat开机启动 以及 开机启动的catalina.bat配置无效解决

一 tomcat 开机启动 免安装版本的tomcat,要建立环境变量 1 配置jdk 要有JAVA_HOME变量就是你是JDK安装目录 要有JRE_HOME变量 就是你的JRE安装目录 2 新建tomcat变量 新建变量:CATALINA_HOME=...

小叮当_加V
2016/04/05
48
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring boot中swagger2使用

1.pom.xml中添加 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version>......

说回答
10分钟前
0
0
tomcat虚拟路径的几种配置方法

tomcat虚拟路径的几种配置方法 一般我们都是直接引用webapps下面的web项目,如果我们要部署一个在其它地方的WEB项目,这就要在TOMCAT中设置虚拟路径了,Tomcat的加载web顺序是先加载 $Tomcat_ho...

Helios51
22分钟前
1
0
Mac 安装jupyter notebook的过程

MAC台式机 python:mac下自带Python 2.7.10 1.先升级了pip安装工具:sudo python -m pip install --upgrade --force pip 2.安装setuptools 工具:sudo pip install setuptools==33.1.1 3.安装......

火力全開
28分钟前
0
0
导航守卫解释与例子

“导航”表示路由正在发生改变。 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。 记住...

tianyawhl
28分钟前
0
0
Java日志框架-logback配置文件多环境日志配置(开发、测试、生产)(原始解决方法)

说明:这种方式应该算是最通用的,原理是通过判断标签实现。 <!-- if-then form --> <if condition="some conditional expression"> <then> ... </then> </if> ......

浮躁的码农
42分钟前
1
0
FTP传输时的两种登录方式和区别

登录方式 匿名登录 用户名为: anonymous。 密码为:任何合法 email 地址。 授权登录 用户名为:用户在远程系统中的用户帐号。 密码为:用户在远程系统中的用户密码。 区别 匿名登录 只能访问...

寰宇01
43分钟前
0
0
plsql developer 配置监听(不安装oracle客户端)

plsql developer 配置监听(不安装oracle客户端)

微小宝
50分钟前
2
0
数据库(分库分表)中间件对比

本人的宗旨就是,能copy的,绝对不手写。 分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm。 根据一定的规则把数据文件(MYD)和索...

奔跑吧代码
54分钟前
2
0
Netty与Reactor模式详解

在学习Reactor模式之前,我们需要对“I/O的四种模型”以及“什么是I/O多路复用”进行简单的介绍,因为Reactor是一个使用了同步非阻塞的I/O多路复用机制的模式。 I/O的四种模型 I/0 操作 主要...

hutaishi
今天
1
0
【2018.07.16学习笔记】【linux高级知识 20.16-20.19】

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

lgsxp
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部