实例演示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的配置支持多样化的数据源,我们可以采用内存的变量.环境变量.命令行参数.以及各种格式的配置文件作为配置的数据来源.在对配置系统进行系统介绍之前,我们通过几个简单的实例演示一下如何将具有不同来源 ...
随机推荐
- ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
通过service mysql status 命令来查看mysql 的启动状态 报错如下: ERROR! MySQL is not running, but lock file (/var/lock/ ...
- 对 Watchbog Botnet 渗透过程和 Payload 的分析
漏洞利用 CVE-2018-1000861 https://jenkins.io/security/advisory/2018-12-05/ Watchbog在做什么? Watchbog僵尸网络为其所 ...
- flask 密钥问题
RuntimeError RuntimeError: The session is unavailable because no secret key was set. Set the secret_ ...
- 探索安卓热修复框架AndFix的奥秘
虽然阿里的AndFix框架已经出来很长时间了,但是还不了解它的同学依然挺多,接下来就跟着我一起来到AndFix的世界里一起看看,如何达到不用重新安装app就可以修复bug. 1.什么是AndFix? ...
- [SVN] - 使用 TortoiseSVN 进行文件比对非常慢 之 解决
背景 Windows 10 + TortoiseSVN-v1.9.7使用默认的 TortoiseMerge 进行文件比对,打开速度非常非常慢. 解决 禁用 TortoiseMerge / Settin ...
- MappingJackson2JsonView——model转成json
一.ajax请求,返回ModelAndView对象,结果报404: @RequestMapping(value = "/video") public ModelAndView jj ...
- Linux 安装部署 Redis
一.Redis介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多 ...
- 机器学习xgboost参数解释笔记
首先xgboost有两种接口,xgboost自带API和Scikit-Learn的API,具体用法有细微的差别但不大. 在运行 XGBoost 之前, 我们必须设置三种类型的参数: (常规参数)gen ...
- uwsgi flask gevent 测试代码覆盖率(coverage)
目录 可能出现的问题 解决 可能出现的问题 多进程启动 gevent启动 运行的服务可能不会停止 解决 我先参考了一下这一篇文章使用Coverage分析WSGI项目的代码覆盖率,他基本能够解决掉1.2 ...
- javascript语法糖
语法糖(Syntactic sugar),也译为糖衣语法 指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用. 通常来说使用语法糖能够增加程序的可读性,从而减少程序代码 ...