本文不許備從盤古開天地開始講述JVM的種種,相關的文章網上太多了,大多也無非轉來轉去,連圖都差很少。筆者只整理個提綱挈領的學習路線指南,並對本身學習過程當中遇到的坑和容易混淆和忽視的地方做個總結。html
內存區域劃分有多個維度,相同區域在不一樣維度的名稱並不同。以下圖所示java
這兩個概念,不少時候都被當作是同一個概念。實際上,「方法區」是java虛擬機規範中對存放類信息,字段,方法,常量,靜態變量,接口和常量池的內存區域的定義,而「永久代」則是HotSpot VM在1.8版本之前對於方法區的具體實現。因爲java虛擬機規範並無對方法區的具體實現做限制,因此HotSpot VM和JRocket VM對於方法區的實現都是不同的,JRocket中就沒有永久代的概念。而在1.8及1.8之後的版本中,HotSpot VM用"元空間"--metaspace來代替永久代,實現方法區。 這個變化帶來的就是VM參數的變化,全部的PermGen都被替換成了MetaSpace。而且metaSpace再也不使用堆內存,而是使用系統內存。可是該發生的OOM同樣會發生。緣由也基本都是加載到內存中的 class 數量太多或者體積太大。算法
GC算法和GC收集器也是兩個維度的概念。 GC算法包括清除算法(也叫標記清除算法),複製算法,標記-整理算法。 不一樣垃圾收集器針對不一樣的內存區域,採用不一樣的GC算法。 具體介紹,網上相關資料不少,能夠參考這篇文章:blog.csdn.net/xiaoping091…瀏覽器
垃圾收集器經歷了從串行收集器到並行收集器,再到併發收集器的進化過程。這三者的區別以下圖所示tomcat
不一樣版本默認使用的垃圾收集器以及支持開發者定製的垃圾收集器都是不同的 jdk1.7 默認垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代) jdk1.8 默認垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代) jdk1.9 默認垃圾收集器G1 與此同時,經過設置JVM參數也能夠本身選擇垃圾收集器。如要開啓G1垃圾回收器,能夠用-XX:+UseG1GC,支持G1垃圾回收器的JDK最低版本爲JDK 7u4。在用戶本身選擇垃圾收集器的時候,要注意JDK版本的問題。 筆者用表格的形式列出了新生代和老年代的GC收集器的常見搭配方案:併發
頻繁FullGC致使的stop the world的現象,會大大影響系統的穩定性。儘管一代又一代的垃圾收集器的優化,使得stop the world的時間愈來愈短,可是在大型應用中,仍是避之不及。 出發FullGC的狀況有如下幾種:eclipse
一般狀況下,JVM的GC機制能保證應用的正常運行,致使系統頻繁FullGC的緣由百分之九十都是內存溢出(OOM)。OOM分爲如下幾類:jvm
正確設置JVM參數,能夠儘量多地避免系統資源浪費,儘量詳細地掌握系統運行狀況,而且對可能出現的問題防患於未然。ide
Xms:堆初始空間工具
Xmx:堆最大空間
Xmn:年輕代大小
XX:MaxNewSize 新生代最大空間 建議設置爲整個堆的1/3到1/4
XX:NewSize
XX:MaxTenuringThreshold survivor中到老年代中的年齡閾值
Xss:每一個線程的棧大小
java -XX:+PrintCommandLineFlags -version 獲得JDK建議的內存分配大小
tomcat設置catalina.sh:
export JAVA_OPTS="-server –Xms1024m -Xmx1024m -XX:+UseParallelOldGC -verbose:gc -Xloggc:../logs/gc.log
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
-XX:+PrintCommandLineFlagsjvm參數可查看默認設置收集器類型
-XX:+PrintGCDetails亦可經過打印的GC日誌的新生代、老年代名稱判斷
1.本機環境下,推薦一款idea上的插件VisualVM Launcher,實際就是聯動了JDK開發包中自帶的jvisualvm.exe監控軟件。也能夠設置遠程監控。具體使用方法,能夠參考這篇文章https://blog.csdn.net/wngpenghao/article/details/82884874IDEA Java性能分析插件VisualVM Launcher 配置(JAVA VisualVM 與Jconsole配置相同)
2.Linux的相關命令: jstat命令能夠對jvm從各維度進行統計,詳細使用參考jstat命令查看jvm的GC狀況
3.VM參數設置時,指定打印出gc日誌 -Xloggc:../logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 詳細的參數設置以及gc日誌該如何閱讀,能夠參考java之GC日誌該怎麼看
若是是使用jvisualvm就更方便了,直接點擊如圖所示的按鈕便可:
因爲實際工做中,能接觸到JVM機會的機會並很少,因此筆者整理了一些經典實例