在上一次【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是如何做用的有所瞭解啦。