新生代與老年代垃圾收集器實現詳解

在上一節【http://www.javashuo.com/article/p-aomfgfzk-bk.html】中已經開啓GC的第一次實踐,此次繼續其於上一次的例子進行擴展來闡述一些其它的知識,先回顧一下上一節的代碼:html

其中GC參數咱們配置以下:java

其中對於試驗代碼中爲啥要選用字節數組來實驗實際上是有緣由的,由於若是用int的話它佔用4個字節還存在換算的因素存在,而byte則就佔一個字節,因此用它比較好理解,接着基於它來繼續修改程序:mysql

再運行:web

/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/bin/java -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -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.MyTest1
[GC (Allocation Failure) [PSYoungGen: 7167K->432K(9216K)] 7167K->6576K(19456K), 0.0060992 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 432K->0K(9216K)] [ParOldGen: 6144K->6487K(10240K)] 6576K->6487K(19456K), [Metaspace: 2649K->2649K(1056768K)], 0.0049758 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

其中多出了一個Full GC,下面對它的日誌進行一下解讀:sql

那這單詞啥意思呢?apache

啥意思。。不懂,反正就是其中發生Full GC的一個緣由唄,其中要特別注意的是:它產生的直接後果就是會出現Stop The World,簡單STW這種狀況,也就是業務線程會暫停一段時間,等它完成GC以後業務線程纔會繼續的恢復執行,因此,在平常的JVM的調優中應該盡最大努力避免出現Full GC的狀況,由於它會致使新生代、老年代、元空間都會進行垃圾回收,下面繼續看日誌:數組

接下來再來看一個神奇的現象,咱們將字節擴大再來看運行效果:jvm

爲何???其實這裏有一個理論能夠解釋:「若是在新生代中已經沒法容納下一個新建立的對象的話,該新對象會直接在老年代來誕生」,那結合目前我們程序來解釋,因爲咱們的新生代設置的總大小爲10M:ide

而新生代由三個區域組成,如:gradle

因此此時Eden空間應該是8M,而咱們前三個字節已經申請了7M空間了:

當咱們再新建一個4M的空間時,很顯然該對象不能在Eden空間存放了,因此此時會將該4M的對象直接放到老年代裏面來存放,因此在老年代中咱們能夠看到已用空間就恰好是4M多,以下:

最後再來介紹新生代和老年代使用的垃圾器的使用狀況:

它表示:Parallel Scavenge (新生代垃圾收集器),其實上節【http://www.javashuo.com/article/p-aomfgfzk-bk.html】也已經說明過,再來回顧一下當時的理論:

它表示:Parallel Old(老年代垃圾收集器),也一樣回顧一下當時的理論說明【http://www.javashuo.com/article/p-xcmnozpx-ge.html】:

也就是說JDK中新生代和老年代默認的垃圾回收器爲以上兩種,固然不一樣的JDK可能默認的垃圾收集器不太同樣,我目前使用的JDK版本爲:

相關文章
相關標籤/搜索