实例演示MaxTenuringThreshold参数及阈值动态调整策略
在上一次【https://www.cnblogs.com/webor2006/p/11031563.html】学习了一个新的JVM对象晋升到老年代的参数“MaxTenuringThreshold”,它的具体作用回忆一下:

简单来说就是用来控制哪些对象的年龄超过了这个最大值就会晋升到老年代,而对于对象晋升的参数其实在之前还有一个类似的【https://www.cnblogs.com/webor2006/p/11025817.html】,如下:

它有个注意事项就是需要配合着这个参数一起使用:

它是用来控制当对象的大小达到多少时,则会晋升为老年代,而上一次控制的是对象的年龄,维度不一样。
这次会用一个综合的例子来对上一次学习的“MaxTenuringThreshold”参数透彻的理论它在对象晋升中发挥的作用,首先新建一个类:


这程序编写有啥意思呢,其实就是通过调用myGc方法来创建对象,然后当myGc方法执行完之后它里面的对象会立马回收,来查看整个GC的一个情况,接着再重复多调几次:

最后再定义三个字节数组,然后再执行myGc(),如下:

好,至此整个例子就编写完了,之所以程序写得这么绕一切都是为了说明"MaxTenuringThreshold"这个参数在gc中所发挥的作用,目前在不加jvm参数之前直接运行结果是比较平淡无奇的:

接着咱们给增加JVM的参数,来观看整个GC的情况,基本上大多数参数都是之前使用过的,也有新参数,下面来加一下:

紧接着第四参数为新参数,如下:

该参数的作用是当某一个survivor空间已经存活的对象如果已经占据了这个survivor空间的60%,那么会重新计算晋升的阈值而不是直接使用"MaxTenuringThreshold"配置的值,比如说Survivor空间是10M的大小,也就是说Survivor空间中已存活的对象的容量已经超过了6M的话,就会重新计算对象晋升的阈值了,而不是使用"MaxTenuringThreshold"所设置的值了,接着继续设置参数:





最后一个参数则为我们讨论的主角:

接下来运行看下结果,此时的结果就异常的丰富了:
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/bin/java -verbose:gc -Xms200M -Xmn50M -XX:TargetSurvivorRatio=60 -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=3 -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/tools.jar:/Users/xiongwei/Documents/workspace/IntelliJSpace/jvm_lectue/out/production/classes:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/mysql/mysql-connector-java/5.1.34/46deba4adbdb4967367b013cbc67b7f7373da60a/mysql-connector-java-5.1.34.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/cglib/cglib/3.2.0/bced5c83ed985c080a24dc5a42b0ca631556f413/cglib-3.2.0.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/5.0.3/dcc2193db20e19e1feca8b1240dbbc4e190824fa/asm-5.0.3.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant/1.9.4/6d473e8653d952045f550f4ef225a9591b79094a/ant-1.9.4.jar:/Users/xiongwei/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant-launcher/1.9.4/334b62cb4be0432769679e8b94e83f8fd5ed395c/ant-launcher-1.9.4.jar com.jvm.gc.MyTest4
2019-06-18T22:11:29.805-0800: [GC (Allocation Failure) 2019-06-18T22:11:29.805-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age 1: 1401992 bytes, 1401992 total
: 40551K->1397K(46080K), 0.0014185 secs] 40551K->1397K(199680K), 0.0014813 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
111111
2019-06-18T22:11:30.814-0800: [GC (Allocation Failure) 2019-06-18T22:11:30.814-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age 1: 340728 bytes, 340728 total
- age 2: 1390544 bytes, 1731272 total
: 42136K->1786K(46080K), 0.0036079 secs] 42136K->1786K(199680K), 0.0036664 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
222222
2019-06-18T22:11:31.827-0800: [GC (Allocation Failure) 2019-06-18T22:11:31.827-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age 1: 56 bytes, 56 total
- age 2: 340080 bytes, 340136 total
- age 3: 1390200 bytes, 1730336 total
: 42304K->1846K(46080K), 0.0015881 secs] 42304K->1846K(199680K), 0.0016395 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
333333
2019-06-18T22:11:32.839-0800: [GC (Allocation Failure) 2019-06-18T22:11:32.839-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age 1: 56 bytes, 56 total
- age 2: 56 bytes, 112 total
- age 3: 340056 bytes, 340168 total
: 42569K->636K(46080K), 0.0034541 secs] 42569K->2005K(199680K), 0.0034946 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
444444
2019-06-18T22:11:33.849-0800: [GC (Allocation Failure) 2019-06-18T22:11:33.849-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 1 (max 3)
- age 1: 3145832 bytes, 3145832 total
- age 2: 56 bytes, 3145888 total
- age 3: 56 bytes, 3145944 total
: 41365K->3213K(46080K), 0.0030496 secs] 42734K->4938K(199680K), 0.0030899 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
555555
2019-06-18T22:11:34.859-0800: [GC (Allocation Failure) 2019-06-18T22:11:34.859-0800: [ParNew
Desired survivor size 3145728 bytes, new threshold 3 (max 3)
- age 1: 56 bytes, 56 total
: 43946K->17K(46080K), 0.0033201 secs] 45671K->4814K(199680K), 0.0033645 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
666666
hello world
Heap
par new generation total 46080K, used 15972K [0x0000000740000000, 0x0000000743200000, 0x0000000743200000)
eden space 40960K, 38% used [0x0000000740000000, 0x0000000740f94990, 0x0000000742800000)
from space 5120K, 0% used [0x0000000742800000, 0x00000007428046f0, 0x0000000742d00000)
to space 5120K, 0% used [0x0000000742d00000, 0x0000000742d00000, 0x0000000743200000)
concurrent mark-sweep generation total 153600K, used 4796K [0x0000000743200000, 0x000000074c800000, 0x00000007c0000000)
Metaspace used 3167K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 349K, capacity 386K, committed 512K, reserved 1048576K Process finished with exit code 0
日志比较多,下面来仔细分析一下,首先可以看到目前的每次GC都会显示时间戳了,如下:

当然就是这个JVM参数起的作用啦:

接下来看第一次GC:

其中这个就是我们新生代指定的垃圾收集器:

该参数发挥的作用:


那这个3M是如何得知的呢?其实是这样的:我们指定新生代的总大小为50M:

而没有指定Eden和Survivor之间比例默认就是按8:1:1来分配的,所以是40:5:5,也就是一个Survivor占据的空间就为5M,而此时咱们又指定了一个这个比例:

而5*60%=3M,所以正好是日志中输出的结果,也就说明了如果Survivor超过3M了则需要重新计算阈值了,继续分析:



接着来看第二次GC:

其中可以发现:

接着分析第三次GC:

此时就得注意啦!!!

接着再看第四次GC:




接着看第五次GC的情况:

这个时候情况就发生了比较大的变化了:

注意:当阈值为1时,会一次性将GC之后的所有年龄的对象都晋升到老年代,继续看最后一次GC:


最后看一下堆的情况:

以上就是对于阈值的一个整体认识,从上面这个具体例子就可以彻底对阈值对于GC是如何作用的有所了解啦。
实例演示MaxTenuringThreshold参数及阈值动态调整策略的更多相关文章
- redis-cluster的实例动态调整内存
当redis.conf中的最大内存配置为10G的时候,恰好程序已经写满了,但是物理主机是有内存的, 此时可以通过config set xxxx xxxx 来设置实例的内存大小,而不需要重启实例. 获取 ...
- 动态线程池(DynamicTp)之动态调整Tomcat、Jetty、Undertow线程池参数篇
大家好,这篇文章我们来介绍下动态线程池框架(DynamicTp)的adapter模块,上篇文章也大概介绍过了,该模块主要是用来适配一些第三方组件的线程池管理,让第三方组件内置的线程池也能享受到动态参数 ...
- iOS学习之路十三(动态调整UITableViewCell的高度)
大概你第一眼看来,动态调整高度是一件不容易的事情,而且打算解决它的第一个想法往往是不正确的.在这篇文章中我将展示如何使图表单元格的高度能根据里面文本内容来动态改变,同时又不必子类化UITableVie ...
- oracle实例内存(SGA和PGA)调整
修改oracle内存占用 >show parameter sga; (查看内存占用情况) NAME TYPE ...
- oracle实例内存(SGA和PGA)调整-xin
一.名词解释 (1)SGA:System Global Area是Oracle Instance的基本组成部分,在实例启动时分配;系统全局域SGA主要由三部分构成:共享池.数据缓冲区.日志缓冲区. ( ...
- 在 Web 级集群中动态调整 Pod 资源限制
作者阿里云容器平台技术专家 王程阿里云容器平台技术专家 张晓宇(衷源) ## 引子 不知道大家有没有过这样的经历,当我们拥有了一套 Kubernetes 集群,然后开始部署应用的时候,我们应该给容器分 ...
- 【大白话系统】MySQL 学习总结 之 缓冲池(Buffer Pool) 如何支撑高并发和动态调整
如果大家对我的 [大白话系列]MySQL 学习总结系列 感兴趣的话,可以点击关注一波. 一.上节回顾 在上节< 缓冲池(Buffer Pool) 的设计原理和管理机制>中,介绍了缓冲池整体 ...
- ASP.NET Core 6框架揭秘实例演示[01]: 编程初体验
作为<ASP.NET Core 3框架揭秘>的升级版,<ASP.NET Core 6框架揭秘>提供了很多新的章节,同时对现有的内容进行大量的修改.虽然本书旨在对ASP.NET ...
- ASP.NET Core 6框架揭秘实例演示[08]:配置的基本编程模式
.NET的配置支持多样化的数据源,我们可以采用内存的变量.环境变量.命令行参数.以及各种格式的配置文件作为配置的数据来源.在对配置系统进行系统介绍之前,我们通过几个简单的实例演示一下如何将具有不同来源 ...
随机推荐
- Ubuntu 新装服务器部署流程
1.设定时区 rm -f /etc/localtime cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 2.配置apt-get源 sed -i ...
- 【GStreamer开发】GStreamer播放教程06——可视化音频
目标 GStreamer有一系列把音频转换成视频的element.他们可以用于科学的目的或者增加音乐播放器的趣味性.本教程展示: 如何允许音频的可视化 如何选择可视化element 介绍 在playb ...
- sql 查找最晚入职员工
题目描述 查找最晚入职员工的所有信息CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`fi ...
- PHP 与操作判断奇偶
/** * 判断奇偶数 * @param $n * @return int */ function isOdd($n){ // $a & $b And(按位与) 将把 $a 和 $b 中都为 ...
- Swing的基本操作
package GUI_experience; import java.awt.*; import java.awt.Container; import java.awt.FlowLayout; im ...
- 2018ACM-ICPC亚洲区域赛南京站I题Magic Potion(网络流)
http://codeforces.com/gym/101981/attachments 题意:有n个英雄,m个敌人,k瓶药剂,给出每个英雄可以消灭的敌人的编号.每个英雄只能消灭一个敌人,但每个英雄只 ...
- 用php的for循环输出四边形,各种三角形和菱形【含空心版本】
<?php // 实心版 //四边形 for( $i = 1; $i <=5; $i++ ){ for( $j = 1; $j <=5; $j++ ){ echo '*'; } ec ...
- sublime自动格式化方法
Sublime 工具自带代码格式化的功能,但在某些场景下格式化代码后并不是我们想要的代码格式,且是点击保存ctrl+s才触发的格式代码事件,so,为关闭点击ctrl+s格式代码,我们需要改命令 sav ...
- Python 数据结构理解分享
摘要:分享学习Python数据结构的一些理解,主要包含序列(如列表和元组),映射(如字典)以及集合3中基本的数据结构,以及可变和不可变数据类型. Python 中的数据结构是根据某种方式将数据元素组合 ...
- 剪贴板神器:Ditto
ditto – 善用佳软 免费开源的 Windows 管理剪贴板,让你处理文字更高效:Ditto - 少数派