1. 程式人生 > >JVM配置引數詳解

JVM配置引數詳解

一、堆引數設定

-XX:+PrintGC 使用這個引數,虛擬機器啟動後,只要遇到GC就會列印日誌

-XX:+UseSerialGC 配置序列回收器

-XX:+PrintGCDetails 可以檢視詳細資訊,包括各個區的情況

-Xms:設定Java程式啟動時初始化堆大小

-Xmx:設定Java程式能獲得最大的堆大小

-Xmx20m -Xms5m -XX:+PrintCommandLineFlags:可以將隱式或者顯示傳給虛擬機器的引數輸出

二、新生代引數配置

-Xmn:可以設定新生代的大小,設定一個比較大的新生代會減少老年代的大小,這個引數對系統性能以及GC行為有很大的影響,新生代大小一般會設定整個堆空間的1/3到1/4左右。

-XX:SurvivorRatio:用來設定新生代中eden空間和from/to空間的比例。含義:-XX:SurvivorRatio=eden/from=eden/to。
不同的堆分佈情況,對系統執行會產生一定的影響,在實際工作中,應該根據系統的特點做出合理的配置,基本策略:儘可能將物件預留在新生代,減少老年代的GC次數。

除了可以設定新生代的絕對大小(-Xmn),還可以使用(-XX:NewRatio)設定新生代和老年代的比例:-XX:NewRatio=老年代/新生代。

配置執行時引數:

-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails
-XX:+UseSerialGC

三、堆溢位引數配置

在Java程式的執行過程中,如果對空間不足,則會丟擲記憶體溢位的錯誤(Out Of Memory)OOM,一旦這類問題發生在生產環境,則可能引起嚴重的業務中斷,Java虛擬機器提供了-XX:+HeapDumpOnOutOfMemoryError,
使用該引數可以在記憶體溢位時匯出整個堆資訊,與之配合使用的還有引數-XX:HeapDumpPath,可以設定匯出堆的存放路徑。
記憶體分析工具:Memory Analyzer

配置執行時引數-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Demo3.dump

四、棧引數配置

Java虛擬機器提供了引數-Xss來指定執行緒的最大棧空間,整個引數也直接決定了函式可呼叫的最大深度。

配置執行時引數:-Xss1m

五、方法區引數配置

和Java堆一樣,方法區是一塊所有執行緒共享的記憶體區域,它用於儲存系統的類資訊,方法區(永久區)可以儲存多少資訊可以對其進行配置,在預設情況下,-XX:MaxPermSize為64M,
如果系統執行時生產大量的類,就需要設定一個相對合適的方法區,以免出現永久區記憶體溢位的問題。

-XX:PermSize=64M -XX:MaxPermSize=64M

六、直接記憶體引數配置

直接記憶體也是Java程式中非常重要的組成部分,特別是廣泛用在NIO中,直接記憶體跳過了Java堆,使用Java程式可以直接訪問原生堆空間,因此在一定程度上加快了記憶體空間的訪問速度。

但是說直接記憶體一定就可以提高記憶體訪問速度也不見得,具體情況具體分析。

相關配置引數:-XX:MaxDirectMemorySize,如果不設定,預設值為最大堆空間,即-Xmx。直接記憶體使用達到上限時,就會觸發垃圾回收,如果不能有效的釋放空間,就會引起系統的OOM。

七、物件進入老年代的引數配置

一般而言,物件首次建立會被放置在新生代的eden區,如果沒有GC介入,則物件不會離開eden區,那麼eden區的物件如何進入老年代呢?

通常情況下,只要物件的年齡達到一定的大小,就會自動離開年輕代進入老年代,物件年齡是由物件經歷數次GC決定的,在新生代每次GC之後如果物件沒有被回收,則年齡加1。

虛擬機器提供了一個引數來控制新生代物件的最大年齡,當超過這個年齡範圍就會晉升老年代。

-XX:MaxTenuringThreshold,預設情況下為15

配置執行時引數:-Xmx64M -Xms64M -XX:+PrintGCDetails

結論:物件首次建立會被放置在新生代的eden區,因此輸出結果中from和to區都為0%。

根據設定MaxTenuringThreshold引數,可以指定新生代物件經過多少次回收後進入老年代。另外,大物件新生代eden區無法裝入時,也會直接進入老年代。

JVM裡有個引數可以設定物件的大小超過在指定的大小之後,直接晉升老年代。
-XX:PretenureSizeThreshold=15

引數:-Xmx1024M -Xms1024M -XX:+UseSerialGC -XX:MaxTenuringThreshold=15 -XX:+PrintGCDetails

使用PretenureSizeThreshold可以進行指定進入老年代的物件大小,但是要注意TLAB區域優先分配空間。虛擬機器對於體積不大的物件 會優先把資料分配到TLAB區域中,因此就失去了在老年代分配的機會.

引數:-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB

八、TLAB引數配置

TLAB全稱是Thread Local Allocation Buffer即執行緒本地分配快取,從名字上看是一個執行緒專用的記憶體分配區域,是為了加速物件分配物件而生的。

每一個執行緒都會產生一個TLAB,該執行緒獨享的工作區域,Java虛擬機器使用這種TLAB區來避免多執行緒衝突問題,提高了物件分配的效率。

TLAB空間一般不會太大,當大物件無法在TLAB分配時,則會直接分配到堆上。

-XX:+UseTLAB使用TLAB

-XX:+TLABSize設定TLAB大小

-XX:TLABRefillWasteFraction設定維護進入TLAB空間的單個物件大小,它是一個比例值,預設為64,即如果物件大於整個空間的1/64,則在堆建立物件。

-XX:+PrintTLAB檢視TLAB資訊

-XX:ResizeTLAB自調整TLABRefillWasteFraction閾值。

引數:-XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=102400 -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=100 -XX:-DoEscapeAnalysis -server