在jvm中有不少的參數能夠進行設置,這樣可讓jvm在各類環境中都可以高效的運行。絕大部分的參數保持默認便可。html
jvm的參數類型分爲三類,分別是 : 標準參數 : -help -version -X參數(非標準參數) -Xint -Xcomp -XX參數(使用率較高) -XX:newSize -XX:+UseSerialGC
能夠經過-server或-client設置jvm的運行參數。 (1)它們的區別是Server VM的初始堆空間會大一些,默認使用的是並行垃圾回收器,啓動慢運行快。 (2)Client VM相對來說會保守一些,初始堆空間會小一些,使用串行的垃圾回收器,它的目標是爲了讓JVM的啓動速度更快,但運行速度會比Server VM模式慢些。 (3)JVM在啓動的時候會根據硬件和操做系統自動選擇使用Server仍是Client類型的JVM。 (4)32位操做系統 1)若是是Windows系統,不論硬件配置如何,都默認使用Client類型的JVM。 2)若是是其餘操做系統上,機器配置有2GB以上的內存同時有2個以上CPU的話默認使用server模式,不然使用client模式。 (5)64位操做系統 1)只有server類型,不支持client類型。
jvm的-X參數是非標準參數,在不一樣版本的jvm中,參數可能會有所不一樣,能夠經過java -X查看非標準參數。 -Xmixed:混合模式執行(默認) -Xint:僅解釋模式執行 -Xbootclasspath:(用;分隔的目錄和zip/jar文件)設置搜索路徑以引導類和資源 -Xbootcalsspath/a:(用;分隔的目錄和zip/jar文件) 附加在引導類路徑末尾 -Xbootcalsspath/p:(用;分隔的目錄和zip/jar文件)置於引導類路徑以前 -Xdiag :顯示附加診斷消息 -Xnoclassgc :禁用類垃圾收集 -Xincgc : 啓用增量垃圾收集 -Xloggc:<file> : 將GC狀態記錄在文件中(帶時間戳) -Xbatch :禁用後臺編譯 -Xms<size> : 設置初始java堆大小 -Xmx<size> : 設置最大java堆大小 -Xss<size> : 設置java線程堆棧大小 -Xprof : 輸出cpu配置文件數據 -Xfuture : 啓用最嚴格的檢查,預期未來的默認值 -Xrs : 減小java/VM 對操做系統信號的使用(請參閱文檔) -Xcheck:jni : 對JNI函數執行其餘檢查 -Xshare:off : 不嘗試使用共享類數據 -Xshare:auto : 在可能的狀況下使用共享類數據(默認) -Xshare:on : 要求使用共享類數據,不然將失敗 -XshowSettings:all : 顯示全部設置並繼續 -XshowSettings:vm : 顯示全部與vm相關的設置並繼續 -XshowSettings:properties : 顯示全部屬性設置並繼續 -XshowSetting:locale : 顯示全部與區域設置相關的設置並繼續
在解釋模式(interpreted mode)下,-Xint標記會強制JVM執行全部的字節碼,固然這會下降運行速度,一般低10倍或更多。 (編譯比較快,運行比較慢) -Xcomp參數與它(-Xint)正好相反,JVM在第一次使用時會把全部的字節碼編譯成本地代碼,從而帶來最大程度的優化。 然而,不少應用在使用-Xcomp也會有一些性能損失,固然這比使用-Xint損失的少,緣由是-Xcomp沒有讓JVM啓用JIT編譯器的所有功能。 JIT編譯器能夠對是否須要編譯作判斷,若是全部代碼都進行編譯的話,對於一些只執行一次的代碼就沒有意義了。 ( -Xmixed是混合模式,將解釋模式與編譯模式進行混合使用,由jvm本身決定,這是jvm默認的模式,也是推薦使用的模式。
-xx參數也是非標準參數,主要用於jvm的調優和debug操做。 -xx參數的使用有2種方式,一種是boolean類型,一種是非boolean類型: boolean類型 格式 :-xx:[+-]<name> 表示啓用或禁用<name>屬性 如 :-xx:+DisableExplicitGC 表示禁用手動調用gc操做,也就是說調用System.gc()無效 非boolean類型 格式 :-xx:<name>=<value> 表示<name>屬性的值爲<value> 如 :-xx:NewRatio=1 表示新生代和老年代的比值
-Xms與-Xmx分別是設置jvm的堆內存的初始大小和最大大小。 -Xmx2048m : 等價於-XX:MaxHeapSize,設置JVM最大堆內存爲2048M。 -Xms512m :等價於-XX:InitialHeapSize,設置JVM初始堆內存爲512M。 適當的調整jvm的內存大小,能夠充分利用服務器資源,讓程序跑的更快。
有時候咱們須要查看jvm的運行參數,這個需求可能會存在2中狀況: 第一,運行java命令時打印出運行參數; 第二,查看正在運行的java進程的參數;
運行java命令時打印參數,須要添加-XX:+PrintFlagsFinal參數便可。 其中參數有boolean類型和數字類型,值的操做符是=或:=,分別 表明默認值和被修改的值。 查看全部的參數,用法 :jinfo -flags <進程id> 經過jps 或者 jps -l 查看java進程 查看某一參數的值,用法 :jinfo -flag <參數名> <進程id>
Young年輕區(代) Young區被劃分爲三部分,Eden區和兩個大小嚴格相同的Survivor區,其中,Survivor區間中,某一時刻只有其中一個是被 使用的,另一個留作垃圾收集時複製對象用,在Eden區間變滿的時候,GC就會將存活的對象移到空閒的Survivor區間中 ,根據JVM的策略,在通過幾回垃圾收集後,任然存活於Survivor的對象將被移動到Tenured區間。 Tenured年老區 Tenured區主要保存生命週期長的對象,通常是一些老的對象,當一些對象在Young複製轉移必定的次數之後, 對象就會被 轉移到Tenured區,通常若是系統中用了application級別的緩存,緩存中的對象每每會被轉移到這一區間。 Perm 永久區 Perm代主要保存class,method,filed對象,這部分的空間通常不會溢出,除非一次性加載了不少的類,不過在涉及到熱部 署的應用服務器的時候,有時候會遇到java.lang.OutOfMemoryError : PermGen space的錯誤,形成這個錯誤的很大緣由就 有多是每次都從新部署,可是從新部署後,類的class沒有被卸載掉,這樣就形成了大量的class對象保存在了perm中,這 種狀況下,通常從新啓動應用服務器能夠解決問題。 Virtual區 最大內存和初始內存的差值,就是Virtual區。
由上圖能夠看出,jdk1.8的內存模型是由2部分組成,年輕代 + 年老代。 年輕代:Eden + 2 * Survivor 年老代:OldGen 在jdk1.8中變化最大的Perm區,用Metaspace(元數據空間)進行了替換。 須要特別說明的是 :Metaspace所佔用的內存空間不是在虛擬機內部,而是在本地內存空間中,這也是與1.7的永久代最大的區別所在。 java
移除永久代是爲融合HotSpot JVM與JRockit VM而作出的努力,由於JRockit沒有永久代,不須要配置永久代。 現實使用中,因爲永久代內存常常不夠用或發生內存泄漏,爆出異常java.lang.OutOfMemoryError : PermGen. 基於此,將永久區廢棄,而改元空間,改成了使用本地內存空間。
jstat命令能夠查看堆內存各部分的使用量,以及加載類的數量。命令的格式以下 : jstat[-命令選項][vmid][間隔時間/毫秒][查詢次數]
說明 : Loaded : 加載class的數量 Bytes : 所佔用空間大小 Unloaded : 未加載數量 Bytes : 未加載佔用空間 Time : 時間程序員
jstat -compiler 數組
說明 : Compiled : 編譯數量 Failed : 失敗數量 Invalid : 不可用數量 Time : 時間 FailedType : 失敗類型 FailedMethod : 失敗的方法瀏覽器
jstat -gc 緩存
也能夠指定打印的間隔和次數,每1秒中打印一次,共打印5次 jstat -gc 1000 5 tomcat
說明 : S0C : 第一個Survivor區的大小(KB) S1C : 第二個Survivor區的大小(KB) S0U : 第一個Survivor區的使用大小(KB) S1U : 第二個Survivor區的使用大小(KB) EC : Eden區的大小(KB) EU : Eden區的使用大小(KB) OC : Old區大小(KB) OU : Old使用大小(KB) MC :方法區大小(KB) MU :方法區使用大小(KB) CCSC :壓縮類空間使用大小(KB) CCSU :壓縮類空間使用大小(KB) YGC :年輕代垃圾回收次數 YGCT :年輕代垃圾回收消耗時間 FGC :老年代垃圾回收次數 FGCT : 老年代垃圾回收消耗時間 GCT :垃圾回收消耗總時間服務器
前面經過jstat能夠對jvm堆的內存進行統計分析,而jmap能夠獲取到更加詳細的內容,如 :內存使用狀況的彙總、對內存溢出的定位與分析。 查看內存使用狀況 : jmap -heap <vmid>
查看全部對象,包括活躍以及非活躍的 jmap -histo <pid> | more 查看活躍對象 jmap -histo:live <pid> | more
對象說明 : B : byte C : char D : double F : float I : int J : long Z : boolean [ : 數組,如[I表示int[] [L+類名 :其餘對象網絡
有些時候咱們須要將jvm當前內存中的狀況dump到文件中,而後對它進行分析,jmap也是支持dump到文件中的。 用法 : jmap -dump:format=b,file=dumpFileName <pid> 其中b是表明二進制 示例 : jmap -dump:format=b,file=/tmp/dump.dat 6219
用法 : jhat -port <port> <file> 例如 : jhat -port 9999 /test/dump.dat 這個時候就能夠打開瀏覽器訪問 :127.0.0.2:9999 -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError : 設置初始堆大小和當發生內存溢出時,給內存一個快照並導出一個dump文件 用MAT進行文件分析
有些時候咱們須要查看下jvm中的線程執行狀況,好比,發現服務器的CPU的負載忽然增高了、出現了死鎖、死循環等,咱們 如何分析呢? 因爲程序是正常運行的,沒有任何的輸出,從日誌方面也看不出什麼問題,因此就須要看下jvm的內部線程的執行狀況,而後 再進行分析查找出緣由。 這個時候,就須要藉助於jstack命令了,jstack的做用是將正在運行的jvm的線程狀況進行快照,而且打印出來 : 用法 :jstack <pid>
在java中線程的狀態一共被分紅6種 : 初始態(NEW) 建立一個Thread對象,但還未調用start()啓動線程時,線程處於初始態。 運行態(RUNNABLE),在java中,運行態包括就緒態和運行態。 就緒態 該狀態下的線程已經得到執行所需的全部資源,只要CPU分配執行權就能運行。 全部就緒態的線程存放在就緒隊列中。 運行態 得到CPU執行權,正在執行的線程。 因爲一個CPU同一時刻只能執行一條線程,所以每一個CPU每一個時刻只有一條運行態的線程。 阻塞態(BLOCKED) 當一條正在執行的線程請求某一資源失敗時,就會進入阻塞態。 而在java中,阻塞態專指請求鎖失敗時進入的狀態。 由一個阻塞隊列存放全部阻塞態的線程。 處於阻塞態的線程會不斷請求資源,一旦請求成功,就會進入就緒隊列,等待執行。 等待態(WAITING) 當前線程中調用wait、join、park函數時,當前線程就會進入等待態。 也有一個等待隊列存放全部等待態的線程。 線程處於等待態表示它須要等待其餘線程的指示才能繼續運行。 進入等待態的線程會釋放CPU執行權,並釋放資源(如 :鎖)。 超時等待態(TIMED_WAITING) 當運行中的線程調用sleep(time)、wait、join、parkNanos、parkUntil時,就會進入該狀態; 它和等待態同樣,並非由於請求不到資源,而是主動進入,而且進入後須要其餘線程喚醒; 進入該狀態後釋放CPU執行權和佔有的資源。 與等待態的區別:到了超時時間後自動進入阻塞隊列,開始競爭鎖。 終止態(TERMINATED) 線程執行結束後的狀態。
在運行的程序中,經過命令窗口查看當前正在執行的線程id jps 同經過jstack進行分析 : jstack <vmid>
在輸出的信息中,已經看到,發現了1個死鎖,關鍵看這個 : app
能夠清晰的看到 : Thread2 獲取了<0x00000000f655dc50>的鎖,等待獲取<0x00000000f655dc40>這個鎖 Thread1 獲取了<0x00000000f655dc40>的鎖,等待獲取<0x00000000f655dc50>這個鎖 因而可知,發生了死鎖。 可使用VisualVM工具進行JVM問題的排查
VisualJVM不只是能夠監控本地jvm進程,還能夠監控遠程的jvm進程,須要藉助於JMX技術實現。
JMX(Java Management Extensions,即Java管理擴展)是一個爲應用程序、設備、系統等植入管理功能的框架,JMX能夠跨越一系列操做 平臺、系統體系結構和網絡傳輸協議,靈活的開發無縫集成的系統、網絡和服務管理應用。
想要監控遠程的tomcat,就須要在遠程的tomcat進行對JMX配置,方法以下 : #在tomcat的bin目錄下,修改catalina.sh,添加以下的參數 JAVA_OPTS=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmremote.ssl=false" 這幾個參數的意思是 : #-Dcom.sun.management.jmxremote : 容許使用JMX遠程管理 #-Dcom.sun.management.jmxremote.port=9999 : JMX遠程鏈接端口 #-Dcom.sun.management.jmxremote.authenticate=false : 不進行身份認證,任何用戶均可以鏈接 #-Dcom.sun.management.jmremote.ssl=false : 不使用ssl 設置好之後保存,並重啓tomcat ./startup.sh && tail -f ../logs/catalina.out : 重啓tomcat並顯示啓動日誌 經過VisualVM進行遠程鏈接。 SpringBoot項目是內嵌的tomcat配置方式查看http://www.360doc.com/content/17/1018/20/16915_696185383.shtml