JVM調優並解決OutOfMemoryError,StackOverflowError

  JVM 調優,首先應從內存開始,尤爲是在真正的的web服務部署的時候。由於真正的web服務會比開發的時候花費更多的內存,用來處理多用戶併發的狀況。本人屢次吃過這方面的虧,因此整理一下,但願能給別人以幫助。java

 

       這個年頭變啦,內存變得如大白菜,每一個新裝的機器都2G以上的內存,甚至4G,也不是什麼新聞。而軟件‘吃’內存的狀況則變化不大(除了VIsta)。但 JAVA誕生的時候可不是這樣——95年,想來當年97年,64M的內存還要500元,因此JVM初始化對內存的要不能太大,並且也要考慮老機器的狀況,畢竟如今JRE基本跑在每一個人的機器上。可是JVM初始佔用還停留在幾年前的狀況下,確實沒有跟上軟件和硬件的發展。而像Tomcat, JBoss, Eclipse(尤爲安上MyEclipse插件後),也考慮到每臺機器的內存狀況,因此初始話定義都很低,常常會拋內存溢出Bugweb

 

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

 

     java.lang.StackOverflowError:(不多)服務器

     java.lang.OutOfMemoryErrorheap space(比較常見)併發

     java.lang.OutOfMemoryError: PermGen space (常常出現)框架

 

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

 

       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。若是已是128mEclipse已是128m了),就改爲 256m。我通常在服務器上爲安全起見,改爲256m插件

 

     java.lang.OutOfMemoryErrorheap space或 其它OutOfMemoryError,這個異常實際上跟上面的異常是一個異常,但解決方法不一樣,因此分開來寫。上面那個異常是由於JVMperm區內存區分少了引發的(JVM的內存區分爲 young,old,perm三種)。而這個異常是由於JVM堆內存或者說整體分少了。解決方法是更改 -Xms -Xmx 啓動參數,一般是擴大1倍。xms是管理啓動時最小內存量的,xmx是管裏JVM最大的內存量的。線程

    注:OutOfMemoryError可能有不少種緣由,根據JVM Specification, 可能有一下幾種狀況,我先簡單列出。stackstack分區不能動態擴展,或不足以生成新的線程。Heap:須要更多的內存,而不能得到。Method Area :若是不能知足分配需求。runtime constant pool(Method Area分配內存)不足以建立class or interfacenative method stacks不可以動態擴展,或生成新的本地線程。ip

 

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

 

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

相關文章
相關標籤/搜索