实例演示MaxTenuringThreshold参数及阈值动态调整策略

在上一次【http://www.javashuo.com/article/p-rfwwfgrx-ey.html】学习了一个新的JVM对象晋升到老年代的参数“MaxTenuringThreshold”,它的具体做用回忆一下:html

简单来讲就是用来控制哪些对象的年龄超过了这个最大值就会晋升到老年代,而对于对象晋升的参数其实在以前还有一个相似的【http://www.javashuo.com/article/p-wxafkuil-es.html】,以下:java

它有个注意事项就是须要配合着这个参数一块儿使用:mysql

它是用来控制当对象的大小达到多少时,则会晋升为老年代,而上一次控制的是对象的年龄,维度不同。web

此次会用一个综合的例子来对上一次学习的“MaxTenuringThreshold”参数透彻的理论它在对象晋升中发挥的做用,首先新建一个类:sql

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

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

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

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

紧接着第四参数为新参数,以下:学习

该参数的做用是当某一个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是如何做用的有所了解啦。

相关文章
相关标签/搜索