今天會學習「MaxTenuringThreshold」這樣一個新的JVM參數,編寫的示例仍是會基於上一次的代碼,新建個類,以下:html
接下來給它設置JVM的參數,具體以下:java
而接下來會新增三個參數:mysql
這個在以前已經使用過,只是木有配置到JVM參數中,回憶下:web
其實就是打印出JVM的啓動參數,接下來再添加兩個新的參數:算法
那這倆參數的含義是啥呢?下面來對它們有個認識:sql
-XX:MaxTenuringThreshold做用:在能夠自動調節對象晉升(Promote)到老年代閾值的GC中,設置該閾值的最大值。【啥意思?當一個對象在新生代中經歷過Minor GC以後對象的年齡就+1,原來0歲此時就變爲1了,當又經歷一次回收以後依然沒有被回收則年齡就變爲2了,而咱們給這參數設置的最大參數爲5,假如對象的年齡變爲6超些咱們設置的最大的這個5時,該對象就會重新生代晉升到老年代當中,注意:這裏是一個極其理想的狀況,可是實際它是可能自動調節的,可能年齡到了2還沒達到咱們設定的5也將其對象晉升到老年代了,可是最大值不可能超過咱們設置的這個值的,也就是不可能對象的年齡到了6尚未被晉升】該參數的默認值是15,CMS【Concurrent Mark Sweep收集器,參考:http://www.javashuo.com/article/p-xcmnozpx-ge.html】中默認值爲6,G1中默認爲15【爲啥是15?由於在JVM中,該數值是由四個bit來表示的,因此最大值爲1111,轉換十進制則爲15】。經歷了屢次GC後,存活的對象會在From Survivor和To Survivor之間來回存放,而這裏面的一個前提則是這倆空間有足夠的大小來存放這些數據,在GC算法中,會計算每一個對象年齡的大小,若是達到某個年齡後發現總大小已經大於了一個Survivor空間的50%【也就是在Survivor中有一半以上的空間都已經被屢次GC依然沒有被回收的對象所佔據了】,那麼這時候就須要調整閾值,不能再繼續等到默認的15次GC後才完成晉升,由於這樣會致使Survivor空間不足【這是一件很是可怕的事情,由於會致使不少新的對象直接就晉升到了老年代】,因此須要調整閾值,讓這些存活對象儘快完成晉升,來釋放Survivor空間。apache
-XX:+PrintTenuringDistribution:表示打印年齡爲幾的對象佔多少字節的一些詳細信息。jvm
好,加上了這些參數以後接下來我們來運行一下看輸出:ide
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/bin/java -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+PrintCommandLineFlags -XX:MaxTenuringThreshold=5 -XX:+PrintTenuringDistribution -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.MyTest3 -XX:InitialHeapSize=20971520 -XX:InitialTenuringThreshold=5 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=10485760 -XX:MaxTenuringThreshold=5 -XX:NewSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC [GC (Allocation Failure) Desired survivor size 1048576 bytes, new threshold 5 (max 5) [PSYoungGen: 7167K->496K(9216K)] 7167K->6648K(19456K), 0.0052608 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] [Full GC (Ergonomics) [PSYoungGen: 496K->0K(9216K)] [ParOldGen: 6152K->6487K(10240K)] 6648K->6487K(19456K), [Metaspace: 2649K->2649K(1056768K)], 0.0082365 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] hello world Heap PSYoungGen total 9216K, used 2290K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) eden space 8192K, 27% used [0x00000007bf600000,0x00000007bf83c9a0,0x00000007bfe00000) from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000) to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000) ParOldGen total 10240K, used 6487K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) object space 10240K, 63% used [0x00000007bec00000,0x00000007bf255d40,0x00000007bf600000) Metaspace used 2656K, capacity 4486K, committed 4864K, reserved 1056768K class space used 287K, capacity 386K, committed 512K, reserved 1048576K Process finished with exit code 0
下面稍加解讀一下:學習
很明顯這句的輸出是由於這個JVM參數的影響:
表示新生代晉升的一個閾值狀況,很顯然這個打印就是咱們這節新加的參數所致:
其中"new threshold 5"就是默認初始化的閾值大小爲5,那這個又表明啥意思呢?
其中1048576就是爲1M,由於總新生代的大小爲10M,而8:1:1,那固然survivor的大小就是1M啦。接下來的日誌就是以前看到過的:
好了,此次先對新生代晉升的閾值有個大體的印象,下次會來看一下它是如何動態的變化進行晉升的。