老李分享:JVM調優

老李分享:JVM調優

 

   poptest是國內惟一一家培養測試開發工程師的培訓機構,以學員能勝任自動化測試,性能測試,測試工具開發等工做爲目標。若是對課程感興趣,請你們諮詢qq:908821478,諮詢電話010-84505200。poptest 不斷優化課堂的案例,培養學員實際解決問題的能力。html

當Java程序申請內存,超出VM可分配內純的時候,VM首先可能會GC,若是GC完仍是不夠,或者申請的直接超夠VM可能有的,就會拋出內 存溢出異常。從VM規範中咱們能夠獲得,一下幾種異常。java

java.lang.StackOverflowError:(不多)
java.lang.OutOfMemoryError:heap space(比較常見)
java.lang.OutOfMemoryError: PermGen space (常常出現)
安全

java.lang.OutOfMemoryError: GC overhead limit exceeded(某項操做使用大量內存時發生)服務器

如下分別解釋一下,從最多見的開始:併發

java.lang.OutOfMemoryError: PermGen space 這個異常比較常見,是說JVM裏的Perm內 存區的異常溢出,因爲JVM在默認的狀況下,Perm默認爲64M,而不少程序須要大量的Perm區內 存,尤爲使用到像Spring等框架的時候,因爲須要使用到動態生成類,而這些類不能被GC自動釋放,因此致使OutOfMemoryError: PermGen space異常。解決方法很簡單,增大JVM的 -XX:MaxPermSize 啓動參數,就能夠解決這個問題,如過使用的是默認變量一般是64M[5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.],改爲128M就能夠了,-XX:MaxPermSize=128m。若是已是128m(Eclipse已是128m了),就改爲 256m。我通常在服務器上爲安全起見,改爲256m。框架

java.lang.OutOfMemoryError:heap space或其它OutOfMemoryError,這個異常實際上跟上面的異常是一個異常,但解決方法不一樣,因此分開來寫。上面那個異常是由於JVM的perm區內 存區分少了引發的(JVM的內 存區分爲 young,old,perm三種)。而這個異常是由於JVM堆內 存或者說整體分少了。解決方法是更改 -Xms -Xmx 啓動參數,一般是擴大1倍。xms是管理啓動時最小內 存量的,xmx是管裏JVM最大的內 存量的。
注:OutOfMemoryError可能有不少種緣由,根據JVM Specification, 可能有一下幾種狀況,我先簡單列出。stack:stack分區不能動態擴展,或不足以生成新的線程。Heap:須要更多的內 存,而不能得到。Method Area :若是不能知足分配需求。runtime constant pool(從Method Area分配內 存)不足以建立class or interface。native method stacks不可以動態擴展,或生成新的本地線程。工具

 

java.lang.OutOfMemoryError: GC overhead limit exceeded,這個是JDK6新添的錯誤類型。這個hotspot VM1.6定義的一個策略,是一種保護機制,經過計算GC時間來預測是否須要OOM了,提早拋出異常,防止OOM的發生,官方的定義是:並行/併發回收器在GC回收時間過長會拋出OutOfMemoryError(過長的定義是超過98%的時間用來GC並回收了不到2%的堆內存,用來避免內存太小形成應用不能正常工做。我在JSP導大Excel的時候碰到過。最終解決方案是,關閉該功能,使用—— -XX:-UseGCOverheadLimit,預測OOM有啥用呢?雖然可能不能最終拯救你的應用,可是能夠在掛掉前作最後的掙扎,好比數據保存和保存現場(Heap Dump),固然這個策略會帶來好比加載某一個大內存時頻繁OOM。加入生產環境遇到這個問題,在不知道緣由的狀況下不要簡單規避這個問題,能夠經過-verbose:gc -XX:+PrintGCDetails看一下究竟是什麼緣由形成的異常。一般緣由都是由於年老代(old區)佔用過多致使頻繁FullGC,最終致使GC overhead limit exceed。若是gc log不夠能夠藉助JProfile等工具查看內存佔用,old區是否有內存泄漏。。分析內存泄漏有一個方法 -XX:HeapDumpOnOutOfMemoryError, 這樣OOM時會自動作Heap Dump,能夠拿MAT來排查了。另外留意新生代(young區),若是有過多短暫對象分配,可能也會致使這個異常。post

 

最後說說java.lang.StackOverflowError,老實說這個異常我也沒遇見過,但JVM Specification就提一下,規範上說有一下幾種境況可能拋出這個異常,一個是Stacks裏的線程超過容許的時候,另外一個是當native method要求更大的內 存,而超過native method容許的內 存的時候。根據SUN的文檔,提升-XX:ThreadStackSize=512的值。性能

總的來講調優JVM的內 存,組要目的就是在使用內 存儘量小的,使程序運行正常,不拋出內 純溢出的bug。並且要調好最小內 存,最大內 存的比,避免GC時浪費太多時間,尤爲是要儘可能避免FULL GC。測試

 

補充:因爲JDK1.4新增了nio,而nio的buffer分配內存比較特殊(讀寫流能夠共享內存)。若是有大量數據交互,也可能致使java.lang.OutOfMemoryError。相應的JDK新增了一個特殊的參數:-XX:MaxDirectMemorySize 默認是64M,能夠改大些如128M。

 -XX:MaxDirectMemorySize=<size>Specifies the maximum amount of memory in bytes that the Java™ NIO library can allocate for direct memory buffers. The default is 64 megabytes, which corresponds to-XX:MaxDirectMemorySize=64m . The use of direct memory buffers can minimize the copying cost when doing I/O operations.

相關文章
相關標籤/搜索