JVM的內存配置參數


JVM的結構問題:JVM分兩塊:PermanentSapce和HeapSpace,

HeapSpace = 【old + new{=Eden,from,to}】

PermantSpace主要負責存放加載Class類級別的class本身,method,field等反射對象,一般不用配置,JVM的Heap區可以通過-X參數來設定。

當一個URL被訪問時,內存申請如下:

A. JVM會試圖為相關Java對象在Eden中初始化一塊內存區域;

B. 當Eden空間足夠時,內存申請結束。否則到下一步;

C. JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收), 釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區;

D. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區;

E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級;

F. 完全垃圾收集后,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現”out of memory錯誤。

JVM參數介紹和調優建議:

Xms/Xmx:定義NEW+OLD段的總尺寸,ms為JVM啟動時NEW+OLD的內存大小;mx為最大可占用的NEW+OLD內存小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷;

NewSize/MaxNewSize:定義單獨NEW段的尺寸,NewSize為JVM啟動時NEW的內存大小;MaxNewSize為最大可占用的NEW的內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷;

 

Xms/Xmx和NewSize/MaxNewSize定義好后,OLD區間也自然定義完畢了,即OLD區初始大小=(Xms-NewSize),OLD區最大可占用大小=(Xmx-MaxNewSize);
    PermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的內存大小;MaxPermSize為最大可占用的Perm內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷;

SurvivorRatio:設置Survivor空間和Eden空間的比例。

以上各值的最大值與初始值的差值為各區段的virtual區,這部分保留的內存不會被其他進程使用。

內存溢出的可能性
 

   1. OLD段溢出
      這種內存溢出是最常見的情況之一,產生的原因可能是:
        1) 設置的內存參數過小(Xms/Xmx, NewSize/MaxNewSize)
        2) 程序問題
           單個程序持續進行消耗內存的處理,如循環幾千次的字符串處理,對字符串處理應建議使用StringBuffer。此時不會報內存溢出錯,卻會使系統持續垃圾收集,無法處理其它請求,相關問題程序可通過Thread Dump獲取(見系統問題診斷一章)單個程序所申請內存過大,有的程序會申請幾十乃至幾百兆內存,此時JVM也會因無法申請到資源而出現內存溢出,對此首先要找到相關功能,然后交予程序員修改,要找到相關程序,必須在Apache日志中尋找。當Java對象使用完畢后,其所引用的對象卻沒有銷毀,使得JVM認為他還是活躍的對象而不進行回收,這樣累計占用了大量內存而無法釋放。由於目前市面上還沒有對系統影響小的內存分析工具,故此時只能和程序員一起定位。

2. Perm段溢出
 

      通常由於Perm段裝載了大量的Servlet類而導致溢出,目前的解決辦法:
       1) 將PermSize擴大,一般256M能夠滿足要求
       2) 若別無選擇,則只能將servlet的路徑加到CLASSPATH中,但一般不建議這么處理
    3. C Heap溢出
       系統對C Heap沒有限制,故C Heap發生問題時,Java進程所占內存會持續增長,直到占用所有可用系統內存

jvm參數設置

1: heap size 
a: -Xmx<n> 
指定 jvm 的最大 heap 大小 , 如 :-Xmx=2g 

b: -Xms<n> 
指定 jvm 的最小 heap 大小 , 如 :-Xms=2g , 高並發應用, 建議和-Xmx一樣, 防止因為內存收縮/突然增大帶來的性能影響。 

c: -Xmn<n> 
指定 jvm 中 New Generation 的大小 , 如 :-Xmn256m。 這個參數很影響性能, 如果你的程序需要比較多的臨時內存, 建議設置到512M, 如果用的少, 盡量降低這個數值, 一般來說128/256足以使用了。 

d: -XX:PermSize=<n> 
指定 jvm 中 Perm Generation 的最小值 , 如 :-XX:PermSize=32m。 這個參數需要看你的實際情況,。 可以通過jmap 命令看看到底需要多少。 

e: -XX:MaxPermSize=<n> 
指定 Perm Generation 的最大值 , 如 :-XX:MaxPermSize=64m 

f: -Xss<n> 
指定線程桟大小 , 如 :-Xss128k, 一般來說,webx框架下的應用需要256K。 如果你的程序有大規模的遞歸行為,請考慮設置到512K/1M。 這個需要全面的測試才能知道。 不過,256K已經很大了。 這個參數對性能的影響比較大的。 

g: -XX:NewRatio=<n> 
指定 jvm 中 Old Generation heap size 與 New Generation 的比例 , 在使用 CMS GC 的情況下此參數失效 , 如 :-XX:NewRatio=2 

h: -XX:SurvivorRatio=<n> 
指 定 New Generation 中 Eden Space 與一個 Survivor Space 的 heap size 比例 ,-XX:SurvivorRatio=8, 那么在總共 New Generation 為 10m 的情況下 ,Eden Space 為 8m 

i: -XX:MinHeapFreeRatio=<n> 
指定 jvm heap 在使用率小於 n 的情況下 ,heap 進行收縮 ,Xmx==Xms 的情況下無效 , 如 :-XX:MinHeapFreeRatio=30 

j: -XX:MaxHeapFreeRatio=<n> 
指定 jvm heap 在使用率大於 n 的情況下 ,heap 進行擴張 ,Xmx==Xms 的情況下無效 , 如 :-XX:MaxHeapFreeRatio=70 

k: -XX:LargePageSizeInBytes=<n> 
指定 Java heap 的分頁頁面大小 , 如 :-XX:LargePageSizeInBytes=128m 

2: garbage collector 

a: -XX:+UseParallelGC 
指 定在 New Generation 使用 parallel collector, 並行收集 , 暫停 app threads, 同時啟動多個垃圾回收 thread, 不能和 CMS gc 一起使用 . 系統噸吐量優先 , 但是會有較長長時間的 app pause, 后台系統任務可以使用此 gc 

b: -XX:ParallelGCThreads=<n> 
指定 parallel collection 時啟動的 thread 個數 , 默認是物理 processor 的個數 , 

c: -XX:+UseParallelOldGC 
指定在 Old Generation 使用 parallel collector 

d: -XX:+UseParNewGC 
指定在 New Generation 使用 parallel collector, 是 UseParallelGC 的 gc 的升級版本 , 有更好的性能或者優點 , 可以和 CMS gc 一起使用

e: -XX:+CMSParallelRemarkEnabled 
在使用 UseParNewGC 的情況下 , 盡量減少 mark 的時間 

f: -XX:+UseConcMarkSweepGC 
指 定在 Old Generation 使用 concurrent cmark sweep gc,gc thread 和 app thread 並行 ( 在 init-mark 和 remark 時 pause app thread). app pause 時間較短 , 適合交互性強的系統 , 如 web server 

g: -XX:+UseCMSCompactAtFullCollection 
在使用 concurrent gc 的情況下 , 防止 memory fragmention, 對 live object 進行整理 , 使 memory 碎片減少 

h: -XX:CMSInitiatingOccupancyFraction=<n> 
指示在 old generation 在使用了 n% 的比例后 , 啟動 concurrent collector, 默認值是 68, 如 :-XX:CMSInitiatingOccupancyFraction=70 

i: -XX:+UseCMSInitiatingOccupancyOnly 
指示只有在 old generation 在使用了初始化的比例后 concurrent collector 啟動收集 

3:others 

a: -XX:MaxTenuringThreshold=<n> 
指 定一個 object 在經歷了 n 次 young gc 后轉移到 old generation 區 , 在 linux64 的 java6 下默認值是 15, 此參數對於 throughput collector 無效 , 如 :-XX:MaxTenuringThreshold=31 

b: -XX:+DisableExplicitGC 
禁止 java 程序中的 full gc, 如 System.gc() 的調用. 最好加上么, 防止程序在代碼里誤用了。對性能造成沖擊。 

c: -XX:+UseFastAccessorMethods 
get,set 方法轉成本地代碼 

d: -XX:+PrintGCDetails 
打應垃圾收集的情況如 : 
[GC 15610.466: [ParNew: 229689K->20221K(235968K), 0.0194460 secs] 1159829K->953935K(2070976K), 0.0196420 secs] 

e: -XX:+PrintGCTimeStamps 
打應垃圾收集的時間情況 , 如 : 
[Times: user=0.09 sys=0.00, real=0.02 secs] 

f: -XX:+PrintGCApplicationStoppedTime 
打應垃圾收集時 , 系統的停頓時間 , 如 : 
Total time for which application threads were stopped: 0.0225920 seconds

 http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM