關於java.lang.OutOfMemoryError:Java Heap Space 當一個Java應用程序在對大批量數據進行操作時,JVM很容易拋出java.lang.outOfMemoryError:Java Heap Space 的錯誤,即堆棧中的內存用光。
產生OutOfMemoryError的原因 JVM拋出這種錯誤的原因,一是程序代碼本身不夠嚴謹,產生大量的垃圾,甚至因對象使用完沒有立即給它的引用賦空值,導致對象在內存堆積而無法釋放(在循環語句中特別如此),這中錯誤是可以避免的;二是JVM分配的內存值相對過少,導致Java程序無法運行。
針對原因一,由於jvm產生的垃圾是由我們所寫的代碼產生的,質量好的代碼產生的垃圾少,相反就會產生很多垃圾。由於jvm的最大內存不能無限增大,故增大jvm的最大內存應該是在代碼已經達到很優化時才實施的,所以優化程序纔是我們最先要做的。 如何優化程序: 第一,避免死循環。仔細檢查程序,防止出現死循環,這是比較容易檢查的。 第二,可以適當手動回收垃圾,即使調用System.gc()或Runtime.gc()。 第三,應該及時釋放種資源:內存, 數據庫的各種連接。釋放資源的時候不能依賴於java的垃圾自動回收機制,最好也不要用finalize方法,因爲無用單元回收不是一個完全可以確定的過程,作爲低優先級進程,往往是系統沒有內存時才調用垃圾回收進程。
針對原因二,應增加JVM的內存大小。JVM運行時候佔用一定的內存,其大小是有限定的,如果程序在運行時JVM佔用的內存大於某個限度,則會產生內存益處,也就是java.lang.outofmemoryerror 。
增加JVM的內存需要設置一些參數 一般來講,設置JVM的堆棧內存會涉及到下面四個參數:
-Xmx 設置Java Heap最大值,如-Xmx128m ,默認值爲物理內存的1/4,最佳設值應該視物理內存大小及計算機內其他內存開銷而定; -Xms 設置Java Heap初始值,如-Xms64m , Server端JVM最好將-Xms和-Xmx設爲相同值,開發測試機JVM可以保留默認值; -Xmn 設置Java Heap Young區大小,如-Xmn32m , 不熟悉最好保留默認值; - Xss 設置每個線程的Stack大小,如-Xss16m , 不熟悉最好保留默認值; 還有兩個參數是跟非堆棧內存有關的: -XX:MaxPermSize 設置最大非堆內存的大小,如-XX:MaxPermSize=128m,默認是物理內存的1/4 ;
如何設置JVM內存分配 ? 一、當在命令提示符下啓動並使用JVM時: java -Xms256m -Xmx512m -XX:MaxPermSize=512m java -Xmx128m -Xms64m -Xmn32m -Xss16m Test(只對當前運行的類Test生效)
二、當在集成開發環境下(如eclipse/MyEclipse)啓動並使用JVM時有三種方法: 方法1: 在eclipse根目錄下打開eclipse.ini,默認內容爲(這裏設置的是運行當前開發工具的JVM內存分配): -vmargs-vmargs表示以下爲虛擬機設置參數,可修改其中的參數值,也可添加-Xmn,-Xss,另外,eclipse.ini內還可以設置非堆內存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m。 此處設置的參數值可以通過以下配置在開發工具的狀態欄顯示: 在eclipse根目錄下創建文件options,文件內容爲:org.eclipse.ui/perf/showHeapStatus=true 修改eclipse根目錄下的eclipse.ini文件,在開頭處添加如下內容: -debug重新啓動eclipse,就可以看到下方狀態條多了JVM信息。
方法2: 打開eclipse-窗口-首選項-Java-已安裝的JRE(對在當前開發環境中運行的java程序皆生效) 編輯當前使用的JRE,在缺省VM參數中輸入:-Xmx128m -Xms64m -Xmn32m -Xss16m
方法3: 打開eclipse-運行-運行-Java應用程序(只對所設置的java類生效) 選定需設置內存分配的類-自變量,在VM自變量中輸入:-Xmx128m -Xms64m -Xmn32m -Xss16m 注:如果在同一開發環境中同時進行了b和c設置,則b設置生效,c設置無效,如: 開發環境的設置爲:-Xmx256m,而類Test的設置爲:-Xmx128m -Xms64m,則運行Test時生效的設置爲: -Xmx256m -Xms64m
三、當在服務器環境下(如Tomcat)啓動並使用JVM時(對當前服務器環境下所以Java程序生效): 方法1: 設置環境變量 變量名:CATALINA_OPTS 變量值:-Xmx128m -Xms64m -Xmn32m -Xss16m 方法2: 打開Tomcat根目錄下的bin文件夾,編輯catalina.bat,將其中的%CATALINA_OPTS%(共有四處)替換爲:-Xmx128m -Xms64m -Xmn32m -Xss16m
查看JVM使用的內存情況 另外,在程序運行的過程中,我們也可以調用以下方法查看JVM使用的內存情況:
Runtime.getRuntime().maxMemory(); //最大可用內存,對應-Xmx Runtime.getRuntime().freeMemory(); //當前JVM空閒內存 Runtime.getRuntime().totalMemory(); //當前JVM佔用的內存總數,其值相當於當前JVM已使用的內存及freeMemory()的總和 關於maxMemory(),freeMemory()和totalMemory(): maxMemory()爲JVM的最大可用內存,可通過-Xmx設置,默認值爲物理內存的1/4,設值不能高於計算機物理內存; totalMemory()爲當前JVM佔用的內存總數,其值相當於當前JVM已使用的內存及freeMemory()的總和,會隨着JVM使用內存的增加而增加; freeMemory()爲當前JVM空閒內存,因 爲JVM只有在需要內存時才佔用物理內存使用,所以freeMemory()的值一般情況下都很小,而JVM實際可用內存並不等於 freeMemory(),而應該等於maxMemory()-totalMemory()+freeMemory()。及其設置JVM內存分配。
關於GC(垃圾回收) 在一些規模稍大的應用中,JVM的內存設置尤爲重要,想在項目中取得好的效率,GC(垃圾回收)的設置是第一步。 PermGen space:全稱是Permanent Generation space.就是說是永久保存的區域,用於存放Class和Meta信息,Class在被Load的時候被放入該區域Heap space:存放Instance。 GC(Garbage Collection)應該不會對PermGen space進行清理,所以如果你的APP會LOAD很多class的話,就很可能出現PermGen space錯誤。
Java Heap分爲3個區 Young保存剛實例化的對象。當該區被填滿時,GC會將對象移到Old區。Permanent區則負責保存反射對象,本文不討論該區。 JVM的Heap分配可以使用-X參數設定: -Xms
初始Heap大小 -Xmn young generation的heap大小
JVM有2個GC線程 有如下原因: 如果你發現每次GC後,Heap的剩餘空間會是總空間的50%,這表示你的Heap處於健康狀態,許多Server端的Java程序每次GC後最好能有65%的剩餘空間
JVM調優的經驗之談: 1.Server端JVM最好將-Xms和-Xmx設爲相同值。爲了優化GC,最好讓-Xmn值約等於-Xmx的1/3。 注意: 1.增加Heap的大小雖然會降低GC的頻率,但也增加了每次GC的時間。並且GC運行時,所有的用戶線程將暫停,也就是GC期間,Java應用程序不做任何工作。 Stack的設定 -Xss
Stack的大小限制着線程的數量。如果Stack過大就好導致內存溢漏。-Xss參數決定Stack大小,例如-Xss1024K。如果Stack太小,也會導致Stack溢漏。
硬件環境 硬件環境也影響GC的效率,例如機器的種類,內存,swap空間,和CPU的數量。
4種GC 1、第一種爲單線程GC,也是默認的GC,該GC適用於單CPU機器。
設置服務器 JVM內存 Tomcat啓動JVM內存設置: 一、Linux 在/usr/local/apache-tomcat-5.5.23/bin目錄下的catalina.sh添加:JAVA_OPTS='-Xms512m -Xmx1024m'要加“m”說明是MB,否則就是KB了,在啓動tomcat時會報內存不足。 二、Windows
在 catalina.bat最前面加入set JAVA_OPTS=-Xms128m -Xmx350m。如果用startup.bat啓動tomcat,OK設置生效,能夠成功的分配200M內存。但是如果不是執行startup.bat 啓動tomcat而是利用windows的系統服務啓動tomcat服務,上面的設置就不生效了,就是說set JAVA_OPTS=-Xms128m -Xmx350m沒起作用,上面分配200M內存就OutOfMemory了。windows服務執行的是bin/tomcat.exe.他讀取註冊表中 的值,而不是 catalina.bat的設置。 解決辦法: 修改註冊表HKEY_LOCAL_MACHINE/SOFTWARE/Apache Software Foundation/Tomcat Service Manager/Tomcat5/Parameters/JavaOptions 原值爲 -Dcatalina.home="C:/ApacheGroup/Tomcat 5.0" 重起tomcat服務,設置生效。
WebLogic啓動JVM 內存設置 在weblogic中,可以在startweblogic.cmd中對每個domain虛擬內存的大小進行設置,默認的設置是在commEnv.cmd裏面。 JBoss啓動JVM 內存設置 默認可以使用的內存爲64MB
Eclipse啓動JVM 內存設置 在所在目錄下,鍵入
Websphere啓動JVM 內存設置 進入控制檯去設置:應用程序服務器 > server1 > 進程定義 > Java 虛擬機 參考資料: http://blog.csdn.net/cool_rain_man/archive/2010/10/12/5935426.aspx http://www.verybc.com/a/hulianwang/2009/1124/8839.html http://cache.baidu.com/c?m=9d78d513d99b12eb0bfa940f5051913b4d0bd73c61979b423f94ce0887231b1f483ca5fd65351177ced82c395cfa5e5c9df33273200357e6c697950b87e0d77f74df78672b42914710d019abd6167b9c758d1baffc5fbcebed3191a9d2d7dd5f53c851007983f08e510612c96ef01634fe&p=b47e8316d9c533ec08e292755355&user=baidu |
JVM的內存優化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.