本文已經收錄到Github倉庫,該倉庫包含計算機基礎、Java基礎、多執行緒、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~
Github地址
今天來熟悉一下,關于JVM調優常用的一些引數,
X或者XX開頭的都是非標準化引數

意思就是說標準化引數不會變,非標準化引數可能在每個JDK版本中有所變化,但是就目前來看X開頭的非標準化的引數改變的也是非常少,
格式:-XX:[+-]<name> 表示啟用或者禁用name屬性,
例子:-XX:+UseG1GC(表示啟用G1垃圾收集器)
-XX:+PrintCommandLineFlags查看當前JVM設定過的相關引數:

JVM引數分類
根據JVM引數開頭可以區分引數型別,共三類:“-”、“-X”、“-XX”,
標準引數(-):所有的JVM實作都必須實作這些引數的功能,而且向后兼容;
例子:-verbose:class,-verbose:gc,-verbose:jni……
非標準引數(-X):默認jvm實作這些引數的功能,但是并不保證所有jvm實作都滿足,且不保證向后兼容;
例子:Xms20m,-Xmx20m,-Xmn20m,-Xss128k……
非Stable引數(-XX):此類引數各個jvm實作會有所不同,將來可能會隨時取消,需要慎重使用;
例子:-XX:+PrintGCDetails,-XX:-UseParallelGC,-XX:+PrintGCTimeStamps……
堆引數設定
-Xms` 初始堆大小,ms是memory start的簡稱 ,等價于`-XX:InitialHeapSize``-Xmx` 最大堆大小,mx是memory max的簡稱 ,等價于引數`-XX:MaxHeapSize
注意:在通常情況下,服務器專案在運行程序中,堆空間會不斷的收縮與擴張,勢必會造成不必要的系統壓力,
所以在生產環境中,
JVM的Xms和Xmx要設定成大小一樣的,能夠避免GC在調整堆大小帶來的不必要的壓力,
-XX:NewSize=n 設定年輕代大小-XX:NewRatio=n 設定年輕代和年老代的比值,
如:-XX:NewRatio=3,表示年輕代與年老代比值為1:3,年輕代占整個年輕代年老代和的1/4,默認新生代和老年代的比例=1:2,-XX:SurvivorRatio=n 年輕代中Eden區與兩個Survivor區的比值,
注意Survivor區有兩個,默認是8,表示:Eden:S0:S1=8:1:1
如:-XX:SurvivorRatio=3,表示Eden:Survivor=3:2,一個Survivor區占整個年輕代的1/5,
元空間引數
-XX:MetaspaceSize:Metaspace 空間初始大小,如果不設定的話,默認是20.79M,這個初始大小是觸發首次 Metaspace Full GC的閾值,
例如:-XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize:Metaspace 最大值,默認不限制大小,但是線上環境建議設定,
例如:-XX:MaxMetaspaceSize=256M
-XX:MinMetaspaceFreeRatio:最小空閑比,當 Metaspace 發生 GC 后,會計算 Metaspace 的空閑比,如果空閑比(空閑空間/當前 Metaspace 大小)小于此值,就會觸發 Metaspace 擴容,默認值是 40 ,也就是 40%,例如 -XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatio:最大空閑比,當 Metaspace發生 GC 后,會計算 Metaspace 的空閑比,如果空閑比(空閑空間/當前 Metaspace 大小)大于此值,就會觸發 Metaspace 釋放空間,默認值是 70 ,也就是 70%,例如 -XX:MaxMetaspaceFreeRatio=70
建議將
MetaspaceSize和MaxMetaspaceSize設定為同樣大小,避免頻繁擴容,
堆疊引數設定
-Xss:堆疊空間大小,堆疊是執行緒獨占的,所以是一個執行緒使用堆疊空間的大小,
例如:-Xss256K,如果不設定此引數,默認值是1M,一般來講設定成 256K 就足夠了,
收集器引數設定
Serial垃圾收集器(新生代)
開啟:-XX:+UseSerialGC 關閉:-XX:-UseSerialGC //新生代使用Serial 老年代則使用SerialOld
ParNew垃圾收集器(新生代)
開啟 -XX:+UseParNewGC 關閉 -XX:-UseParNewGC //新生代使用功能ParNew 老年代則使用功能CMS
Parallel Scavenge收集器(新生代)
開啟 -XX:+UseParallelOldGC 關閉 -XX:-UseParallelOldGC //新生代使用功能Parallel Scavenge 老年代將會使用Parallel Old收集器
ParallelOl垃圾收集器(老年代)
開啟 -XX:+UseParallelGC 關閉 -XX:-UseParallelGC //新生代使用功能Parallel Scavenge 老年代將會使用Parallel Old收集器
CMS垃圾收集器(老年代)
開啟 -XX:+UseConcMarkSweepGC 關閉 -XX:-UseConcMarkSweepGC
G1垃圾收集器
開啟 -XX:+UseG1GC 關閉 -XX:-UseG1GC
GC策略引數配置
GC停頓時間,垃圾收集器會嘗試用各種手段達到這個時間,比如減小年輕代
-XX:MaxGCPauseMillis
堆占用了多少比例的時候觸發GC,就即觸發標記周期的 Java 堆占用率閾值,默認占用率是整個 Java 堆的 45%
-XX:InitiatingHeapOccupancyPercent=n
新生代可容納的最大物件,大于則直接會分配到老年代,0代表沒有限制,
-XX:PretenureSizeThreshold=1000000 //
進入老年代最小的GC年齡,年輕代物件轉換為老年代物件最小年齡值,默認值7
-XX:InitialTenuringThreshol=7
升級老年代年齡,最大值15
-XX:MaxTenuringThreshold
GC并行執行執行緒數
-XX:ParallelGCThreads=16
禁用 System.gc(),由于該方法默認會觸發 FGC,并且忽略引數中的 UseG1GC 和 UseConcMarkSweepGC,因此必要時可以禁用該方法,
-XX:-+DisableExplicitGC
設定吞吐量大小,默認99
XX:GCTimeRatio
打開自適應策略,各個區域的比率,晉升老年代的年齡等引數會被自動調整,以達到吞吐量,停頓時間的平衡點,
XX:UseAdaptiveSizePolicy
設定GC時間占用程式運行時間的百分比
GCTimeRatio
Dump例外快照
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath
堆記憶體出現OOM的概率是所有記憶體耗盡例外中最高的,出錯時的堆內資訊對解決問題非常有幫助,
所以給JVM設定這個引數(-XX:+HeapDumpOnOutOfMemoryError),讓JVM遇到OOM例外時能輸出堆內資訊,并通過(-XX:+HeapDumpPath)引數設定堆記憶體溢位快照輸出的檔案地址,
這對于特別是對相隔數月才出現的OOM例外尤為重要,
-Xms10M -Xmx10M -Xmn2M -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=D:\study\log_hprof\gc.hprof
-XX:OnOutOfMemoryError
表示發生OOM后,運行jconsole.exe程式,
這里可以不用加“”,因為jconsole.exe路徑Program Files含有空格,利用這個引數,我們可以在系統OOM后,自定義一個腳本,可以用來發送郵件告警資訊,可以用來重啟系統等等,
-XX:OnOutOfMemoryError="C:\Program Files\Java\jdk1.8.0_151\bin\jconsole.exe"
8G記憶體的服務器該如何設定
java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-Xmx3500m 設定JVM最大可用記憶體為3550M,
-Xms3500m 設定JVM``初始記憶體為3550m,此值可以設定與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配記憶體,-Xmn2g 設定年輕代大小為2G,
整個堆大小=年輕代大小 + 年老代大小 + 方法區大小
-Xss128k 設定每個執行緒的堆疊大小,
JDK1.5以后每個執行緒堆疊大小為1M,以前每個執行緒堆疊大小為256K,更具應用的執行緒所需記憶體大小進行調整,在相同物理記憶體下,減小這個值能生成更多的執行緒,但是作業系統對一個行程內的執行緒數還是有限制的,不能無限生成,經驗值在3000~5000左右,
-XX:NewRatio=4 設定年輕代(包括Eden和兩個Survivor區)與年老代的比值(除去持久代),設定為4,則年輕代與年老代所占比值為1:4,年輕代占整個堆疊的1/5 ,
-XX:SurvivorRatio=4 設定年輕代中Eden區與Survivor區的大小比值,
設定為4,則兩個Survivor區與一個Eden區的比值為2:4,一個Survivor區占整個年輕代的1/6 -XX:MaxPermSize=16m 設定持久代大小為16m,
-XX:MaxTenuringThreshold=0 設定垃圾最大年齡,
如果設定為0的話,則年輕代物件不經過Survivor區,直接進入年老代,對于年老代比較多的應用,可以提高效率,如果將此值設定為一個較大值,則年輕代物件會在Survivor區進行多次復制,這樣可以增加物件在年輕代的存活時間,增加在年輕代即被回收的概論,
專案中,GC日志配置
比如,我們啟動一個user-service專案:
java
-XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:+PrintHeapAtGC -XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=20M
-Xloggc:/opt/user-service-gc-%t.log
-jar user-service-1.0-SNAPSHOT.jar
引數解釋:
-Xloggc:/opt/app/ard-user/user-service-gc-%t.log 設定日志目錄和日志名稱
-XX:+UseGCLogFileRotation 開啟滾動生成日志
-XX:NumberOfGCLogFiles=5 滾動GC日志檔案數,默認0,不滾動
-XX:GCLogFileSize=20M GC檔案滾動大小,需開啟UseGCLogFileRotation
-XX:+PrintGCDetails 開啟記錄GC日志詳細資訊(包括GC型別、各個操作使用的時間),并且在程式運行結束列印出JVM的記憶體占用情況
-XX:+ PrintGCDateStamps 記錄系統的GC時間
-XX:+PrintGCCause 產生GC的原因(默認開啟)
專案中沒用過怎么辦?
對于很多沒用過的人來說,面試官問專案中這些引數是怎么用?此時,很容易選擇妥協,傻傻的回答沒用過,
偷偷的告訴你,很多面試官也沒有用過,
另外,你可以自己搞個小專案,把JVM引數設定小點,使用測驗工具JMeter,多執行緒測驗一下,
在代碼里可以自己編造以下問題:
記憶體溢位
記憶體泄漏
堆疊溢位
然后使用JVM引數進行調優,或者通過JVM工具和相關命令找到問題,然后解決問題,
自己一定要動手,別人永遠是別人的,自己體會了自己經歷了,那才是自己的,
最后給大家分享一個Github倉庫,上面有大彬整理的300多本經典的計算機書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、作業系統、計算機網路、資料結構和演算法、機器學習、編程人生等,可以star一下,下次找書直接在上面搜索,倉庫持續更新中~


Github地址
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548331.html
標籤:其他
