在上一次【http://www.javashuo.com/article/p-bwmrkyij-ca.html】中實驗了一個重新生代到老年代競升的狀況,得出一個這樣的結果,回憶下:html
其實對於JVM來講,它提供了相應的一些參數來指定對象達到了多少的時候直接就能夠在老年代分配而不是在新生代來分配,新生代是喜歡小的並且生命短暫的對象,因此下面來作實驗,先新建一個類,示例代碼基本上跟上一次相似:java
接下來須要介紹一個打印JVM啓動的默認參數的命令,以下:mysql
下面具體來看一下這些默認JVM啓動參數的含義:web
它其實等價於咱們在上一個程序添加的JVM的這個參數:sql
表示堆的初始大小。apache
其實等價於:jvm
表示堆的最大大小。ide
啥意思?這裏作個瞭解:由於32位的尋址空間跟64位的尋址空間顯然是不同的,64位的尋址空間要更大一些,可是若是從32位牽移到64位的虛擬機上,因爲尋址空間變大,因此相應的指針也會變大,也就是說JVM在啓動時佔用的內存空間也更多,當加上此JVM啓動參數以後則會針對特定【具體哪幾類這裏就不過多說明,能夠網上搜尋,這裏僅作了解】的指針進行一個壓縮,使得JVM佔用的內存空間更小。工具
這也就是爲啥咱們在上一次的程序中看到的新生代和老年代的垃圾收集器默認就是:學習
緣由就在於JVM默認指定的垃圾收集器是指定的ParallelGC。有了這樣的一個背景知識以後,接下來我們給這個新的程序增長一些JVM參數,有一些參數跟上一次設置的差很少,但也有些是新的,先將上一次的參數直接拷貝過來:
緊接着再增長一些新的參數,以下:
其實在以前的理論學習中也有說明,回憶一下:
因此,我們改一下程序,直接申請一個大於這個值的內存大小,以下:
這是爲啥呢?其實還得指定另一個參數,咱們指定的「-XX:PretenureSizeThreshold=4194304」纔會生效,這裏須要指定串行收集器才行,啥叫串行收集器,回顧下以前的理論:
而對應的JVM參數爲:
因此我們加上該JVM參數:
再運行,此時看到的結果會大不同:
其中關鍵處能夠發現,咱們申請的5M空間直接就進入到了老年代了,以下:
因此經過上面的方式就能指定老年代的閾值,好,我們仍是回到ParallelGC,也就是將最後一個JVM參數刪掉,來回顧下「若是在新生代中已經沒法容納下一個新建立的對象的話,該新對象會直接在老年代來誕生」的狀況:
而後我們直接來申請8M的空間,這樣在Eden新生代中確定容納不下:
那若是繼續擴大申請的內存又會是啥輸出呢,這裏改到10M:
/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/bin/java -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=4194304 -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.MyTest2 [GC (Allocation Failure) [PSYoungGen: 1023K->432K(9216K)] 1023K->440K(19456K), 0.0009855 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 432K->416K(9216K)] 440K->424K(19456K), 0.0007116 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 416K->0K(9216K)] [ParOldGen: 8K->343K(10240K)] 424K->343K(19456K), [Metaspace: 2649K->2649K(1056768K)], 0.0048980 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 0K->0K(9216K)] 343K->343K(19456K), 0.0004381 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 0K->0K(9216K)] [ParOldGen: 343K->331K(10240K)] 343K->331K(19456K), [Metaspace: 2649K->2649K(1056768K)], 0.0068370 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.jvm.gc.MyTest2.main(MyTest2.java:6) Heap PSYoungGen total 9216K, used 246K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) eden space 8192K, 3% used [0x00000007bf600000,0x00000007bf63d890,0x00000007bfe00000) from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000) to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000) ParOldGen total 10240K, used 331K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) object space 10240K, 3% used [0x00000007bec00000,0x00000007bec52d00,0x00000007bf600000) Metaspace used 2681K, capacity 4486K, committed 4864K, reserved 1056768K class space used 290K, capacity 386K, committed 512K, reserved 1048576K Process finished with exit code 1
可見直接拋內存溢出異常了,並且此時日誌的輸出信息也比較多,稍加分析:
並且有個小細節,此時FULL GC的緣由變爲了:
而非以前我們看到的:
接下來我們準備用以前學習的可視化監測工做來瞅一下GC的狀況,先仍是將串行的參數加上,並程序進行還原:
爲了能監視,咱們將程序進行一下休眠:
首先我們用jvisualvm來查看一下:
此時會看到會有GC出現,是由於可視化的工具會attach到咱們的進程上會形成GC動做,我們看一下堆的狀況:
另外我們還能夠經過該工具主動讓JVM進行GC,以下:
好比我連續點3次,則會出現三次FULL GC:
此時的GULL GC的緣由就變爲System.gc()了,咱們知道對於「System.gc()」它被調用以後JVM並不必定會立馬執行,可是它的意義仍是挺大的,爲啥,由於對於GC點的出現正常只支在咱們建立對象的那一刻纔會引發,有了這個命令就讓咱們手動去在想要GC的時候儘量的發生做用。
好,接下來我們再換一個可視化的工具,換成jmc:
其中再看一下診斷命令:
其實它就是來自於jcmd命令中,如咱們也能夠用這個命令來查看進程JVM的參數信息,以下:
對應的在診段命令中執行一下也能夠瞅見:
另外該工具中的飛行記錄器也能夠瞅一下內存狀況:
固然具體裏面有何用還得是在將來有須要再慢慢熟悉。