這篇文章主要講解了“JVM的參數有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“JVM的參數有哪些”吧!
垃圾收集策略:
垃圾收集的3種模式:
Serial GC
串行收集:適合內存有限的情況,回收慢。
Parallel GC
并行收集:效率高,當Heap較大時,系統暫停時間較長。
CMS GC
并發收集:Old區回收暫停時間短,整個GC耗時較長、比較耗CPU資源。
參數:
Serial GC:
-XX:+UseSerialGC 使用串行收集模式,即使用Serail + Serail Old 進行回收。虛擬機運行在client模式下的默認選項。
Parallel GC:
-XX:+UseParallelGC 使用Parallel Scavenge + Serail Old 進行回收。虛擬機運行在server模式下的默認選項。
-XX:+UseParNewGC 使用ParNew + Serial Old 來進行回收。設置新生代的收集器為ParNew收集器(并行收集器)。該設置默認是關閉的,打開該開關后,jvm會使用 ParNew + Serial Old 來進行gc。
-XX:ParallelGCThreads ParNew收集器的收集線程數,默認與CPU的數量相同。
-XX:+UseParallelOldGC 使用Parallel Scavenge + Parallel Old進行回收。
CMS GC:
-XX:+UseConcMarkSweepGC 使用ParNew + CMS收集器(并發收集失敗(Concurrent Mode Failure)后使用Serial Old收集器)
-XX:+CMSParallelRemarkEnabled 開啟并行remark,以減少remark時程序暫停的時間。
-XX:CMSInitiatingOccupancyFraction=70 當老年代的空間被占用70%后,CMS收集器開始gc。
1>JVM會收集對象分配和釋放的運行時數據,并且通過分析這些數據來決定什么時候應該進行一次gc(即:啟動一次CMS垃圾收集器)。
2>為了引導這一過程,JVM會在啟動CMS收集器前進行一些線索查找,該線索由-XX:CMSInitiatingOccupancyFraction來設置,該值表示老年代的使用率。
-XX:+UseCMSInitiatingOccupancyOnly 命令JVM不要根據運行時收集的數據來判斷什么時候開始gc,而是根據CMSInitiatingOccupancyFraction的值來判斷是否進行CMS收集。注意:一般不會打開該開關。
-XX:+UseCMSCompactAtFullCollection CMS收集器在gc時,允許對老年代進行壓縮,解決因標記-清除算法導致的內存碎片的問題。
-XX:CMSFullGCsBeforeCompaction=0 CMS收集器gc多少次后進行內存壓縮(整理),由于CMS收集器使用的是標記-清除算法,所以CMS在gc后會產生內存碎片,使得運行效率降低。
-XX:+CMSClassUnloadingEnabled 開啟CMS收集器對永久代的gc(默認不會對永久代進行gc)。
-XX:CMSInitiatingPermOccupancyFraction 設置永久代使用到達多少比率時觸發CMS收集器的gc
-XX:+DisableExplicitGC 禁止System.gc(),避免因開發人員不恰當地調用System.gc()方法對系統性能造成的不良的影響。
-Xnoclassgc 禁用類垃圾回收功能,也就避免了同一個類的加載、卸載、(再次用到該類時)再加載的操作,性能會高一點。
1>虛擬機加載類的過程中包含了IO和內存分配等操作,故JVM在加載類時會對性能產生一定的影響。
-XX:+UseFastAccessorMethods 優化原始類型的getter方法的性能,默認開啟。
-XX:+PrintClassHistogram 遇到Ctrl+Break中斷,打印類實例的柱狀信息,與jmap -histo功能相同
-XX:SoftRefLRUPolicyMSPerMB=0 設置每兆堆空閑空間中軟引用(SoftReference)的存活時間,默認值為1(秒)。
1>softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap.
2>SoftReference是在gc時才被回收,故SoftReference實際的存活時間可能比這個設定的值要大。
3>一般情況下,建議設置為0。
輔助信息:
-XX:+PrintGCDetails 打印GC的詳細信息
-XX:+PrintGCTimeStamps 打印GC的時間戳
-XX:+PrintHeapAtGC 打印GC前后堆棧的詳細信息
-Xloggc: 設置gc的log日志。eg:-Xloggc:$CATALINA_BASE/logs/gc.log
堆棧:
【堆】
-Xms 或 -XX:InitialHeapSize 初始堆大小,默認空余堆內存小于40%(MinHeapFreeRatio參數可以調整)時,JVM就會增大堆直到-Xmx的最大限制。
-Xmx 或 -XX:MaxHeapSize 最大堆大小,默認空余堆內存大于70%(MaxHeapFreeRatio參數可以調整)時,JVM會減少堆直到-Xms的最小限制。
-Xmn 新生代大?。?br/> 1>新生代越大也就意味著會有更多的對象在minor GC期間被回收,如果設置的太大,則老年代就變小了,可能會頻繁觸發Full GC,甚至是OOM。
2>如果新生代設置的太小,則會導致minor GC更加頻繁,進而會導致更多的對象直接進入老年代,當老年代已使用的空間到達一定比例時,會觸發Full GC。
-XX:NewSize 設置新生代大小
-XX:NewRatio 新生代(Eden+2個Survivor)最大容量與老年代最大容量的比值,默認為2,即:NewSize : OldSize = 1:2 注意:該參數的值=老年代最大容量大小/新生代最大容量大小。
eg:jstat -gccapacity PID # 查看NGCMX、OGCMN 即可驗證。
-XX:SurvivorRatio 設置Eden與1個Survivor的比值,默認為8,即 Eden : Survivor1 : Survivor2 = 8:1:1
1>Eden越大也就意味著發生minor GC的頻率越低,如果Eden設置的太大,造成Survivor太小,則會導致要回收的對象在minor GC后就直接進入老年代,從而更頻繁地觸發Full GC。
【?!?br/> -Xss 每個線程的棧大?。?br/> 1>在相同物理內存下:減小這個值能生成更多的線程,但是操作系統對一個進程內的線程數是有限制的,不能無限生成(網上說是3k-5k左右,沒有做過測試)。
2>一般比較小的系統,如果棧不是很深,則128k就夠用了,較大的系統則應設置為256k。
3>jdk5之后,每個線程堆棧大小默認為1M。
【永久代】
-XX:PermSize 設置永久代初始值
-XX:MaxPermSize 設置持久代最大值
【其它】
-XX:+TraceClassLoading 跟蹤類加載和卸載的信息,一般我們在排查內存泄露、jar包版本沖突等問題時會添加這個參數。
-XX:-OmitStackTraceInFastThrow
說明:
jdk1.5后,為了提高性能,JVM在以Server模式運行時,當一些異常在代碼里某個特定位置被拋出很多次后,編譯器(C2)會對該方法進行重編譯,重編譯后,若再次出現該異常,則會拋出一個提前準備好的沒有調用棧的異常。通過 -XX:-OmitStackTraceInFastThrow 可以禁用該默認的優化。
官方:
The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions.
For performance purposes, when such an exception is thrown a few times, the method may be recompiled.
After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace.
-XX:LargePageSizeInBytes=128 設置內存頁的大小
-XX:MaxTenuringThreshold GC最大年齡
1>如果設置為0,則新生代對象不經過Survivor區,直接進入老年代。對于老年代中對象比較多的應用,可以提高效率。 2>如果設置為一個較大的值,則新生代對象會在Survivor區進行多次復制,這樣可以增加對象在新生代的存活時間,增加對象在新生代被回收的概率,該參數只有在串行GC時才有效。
域名解析:
-Dsun.net.spi.nameservice.provider.1=dns,sun 指定域名解析器 https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html
舉例:無法解析某個域名,報java.net.UnknownHostException錯誤
解決:啟動的時候添加參數 -Dsun.net.spi.nameservice.provider.1=dns,sun
補充:
-XX:CMSInitiatingOccupancyFraction與-Xmn之間的關系:
內存分配擔保失敗(promontion faild)的原因:
1)Minor GC時,將eden和survivor from中存活的對象復制到survivor to中的時候,如果survivor to容納不下這些對象,那么這些對象將晉升到老年代,
2)此時,如果老年代中剩余的空間也無法容納下這些對象,那么就會導致內存分配擔保失敗(promontion faild),進而引發了full gc。
結論:當新生代與老年代滿足 eden + survivor from <= 老年代剩余的空間 關系時,promontion faild就不會發生。
即:eden + survivor from <= (Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)
由方程組:
Eden / Survivor=SurvivorRatio
Eden + 2Survivor=Xmn
Survivor * SurvivorRatio + 2Survivor = Xmn ===> Survivor = Xmn/(SurvivorRatio+2)
可得出:
Eden + Survivor = Xmn-Survivor = Xmn - Xmn/(SurvivorRatio+2)
即:Xmn - Xmn/(SurvivorRatio+2) <= (Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)
簡化:
CMSInitiatingOccupancyFraction <= (1 - (Xmn-Xmn/(SurvivorRatio+2))/(Xmx-Xmn)) * 100
eg:如果 -Xms8G -Xmx8G -Xmn3G -XX:SurvivorRatio=8,則 CMSInitiatingOccupancyFraction <= (1 - (3-3/(8+2))/(8-3))) = 46%
CMSInitiatingOccupancyFraction低于70% 需要調整xmn或SurvivorRatior值。
===================================================================================
網上某大牛的配置,據稱可以支持每天幾百萬的pv。
JAVA_OPTS="
-Dresin.home=$SERVER_ROOT
-server
-Xms6000M
-Xmx6000M
-Xmn500M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-XX:SurvivorRatio=65536
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:+CMSParallelRemarkEnabled
-XX:CMSInitiatingOccupancyFraction=90
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log"
說明:
1)-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0 表示在新生代中去掉了Survivor,即新生代中只有Eden
===================================================================================
感謝各位的閱讀,以上就是“JVM的參數有哪些”的內容了,經過本文的學習后,相信大家對JVM的參數有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。