以下是從網(wǎng)上找到的關于堆空間溢出的錯誤解決辦法:
java.lang.OutOfMemoryError: Java heap space
===================================================
使用Java程序從數(shù)據(jù)庫中查詢大量的數(shù)據(jù)時出現(xiàn)異常:
java.lang.OutOfMemoryError: Java heap space
在JVM中如果98%的時間是用于GC且可用的 Heap size 不足2%的時候將拋出此異常信息。
JVM堆的設置是指java程序運行過程中JVM可以調(diào)配使用的內(nèi)存空間的設置.
JVM在啟動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)是物理內(nèi)存的1/4??梢岳肑VM提供的-Xmn -Xms -Xmx等選項可進行設置。
例如:java -jar -Xmn16m -Xms64m -Xmx128m MyApp.jar
如果Heap Size設置偏小,除了這些異常信息外,還會發(fā)現(xiàn)程序的響應速度變慢了。GC占用了更多的時間,而應用分配到的執(zhí)行時間較少。
Heap Size 最大不要超過可用物理內(nèi)存的80%,一般的要將-Xms和-Xmx選項設置為相同,而-Xmn為1/4的-Xmx值。
Heap size的 -Xms -Xmn 設置不要超出物理內(nèi)存的大小。否則會提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。
==========================================================
經(jīng)過一個晚上的努力終于完成了一個文件替換指定字符串的程序,但是由于我要替換的全站程序html文件太多,所以eclipse下邊老是在一個目錄結束后報出java.lang.OutOfMemoryError: Java heap space的異常,然后就崩潰了。
我一想肯定是頻繁操作造成來不及回收,于是在每個循環(huán)之后加上一個Thread.sleep(1000),發(fā)現(xiàn)還是到那個目錄下就死掉,于是把1000改成5000,還是到那里死掉,我想可能不是來不及回收這么簡單,或許sun 的JVM里邊剛好對于這種情況不釋放也有可能。
接著我又把啟動的參數(shù)添上一個 -Xmx256M,這回就可以了。
還有:Java堆的管理—垃圾回收提到一下幾點,很不錯,或許可以作為寫程序時候的準則:
?。?)不要試圖去假定垃圾收集發(fā)生的時間,這一切都是未知的。比如,方法中的一個臨時對象在方法調(diào)用完畢后就變成了無用對象,這個時候它的內(nèi)存就可以被釋放。
?。?)Java中提供了一些和垃圾收集打交道的類,而且提供了一種強行執(zhí)行垃圾收集的方法--調(diào)用System.gc(),但這同樣是個不確定的方法。Java 中并不保證每次調(diào)用該方法就一定能夠啟動垃圾收集,它只不過會向JVM發(fā)出這樣一個申請,到底是否真正執(zhí)行垃圾收集,一切都是個未知數(shù)。
?。?)挑選適合自己的垃圾收集器。一般來說,如果系統(tǒng)沒有特殊和苛刻的性能要求,可以采用JVM的缺省選項。否則可以考慮使用有針對性的垃圾收集器,比如增量收集器就比較適合實時性要求較高的系統(tǒng)之中。系統(tǒng)具有較高的配置,有比較多的閑置資源,可以考慮使用并行標記/清除收集器。
(4)關鍵的也是難把握的問題是內(nèi)存泄漏。良好的編程習慣和嚴謹?shù)木幊虘B(tài)度永遠是最重要的,不要讓自己的一個小錯誤導致內(nèi)存出現(xiàn)大漏洞。
?。?)盡早釋放無用對象的引用。
大多數(shù)程序員在使用臨時變量的時候,都是讓引用變量在退出活動域(scope)后,自動設置為null,暗示垃圾收集器來收集該對象,還必須注意該引用的對象是否被監(jiān)聽,如果有,則要去掉監(jiān)聽器,然后再賦空值。
就是說,對于頻繁申請內(nèi)存和釋放內(nèi)存的操作,還是自己控制一下比較好,但是System.gc()的方法不一定適用,最好使用finallize強制執(zhí)行或者寫自己的finallize方法。
================================================
tomcat
遇到TOMCAT出錯:java.lang.OutOfMemoryError: Java heap space,于是查了資料,找到了解決方法:
If Java runs out of memory, the following error occurs:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Java heap size can be increased as follows:
java -Xms<initial heap size> -Xmx<maximum heap size>
Defaults are:
java -Xms32m -Xmx128m
如果你用win
/tomcat/bin/catalina.bat 加上下面的命令:
set JAVA_OPTS=-Xms32m -Xmx256m
如果你用unix/linux
/tomcat/bin/catalina.sh 加上下面的命令:
JAVA_OPTS="-Xms32m -Xmx256m"
=========================================
原因:
使用Java程序從數(shù)據(jù)庫中查詢大量的數(shù)據(jù)時出現(xiàn)異常:
java.lang.OutOfMemoryError: Java heap space
在JVM中如果98%的時間是用于GC且可用的 Heap size 不足2%的時候將拋出此異常信息。
JVM堆的設置是指java程序運行過程中JVM可以調(diào)配使用的內(nèi)存空間的設置.JVM在啟動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)是物理內(nèi)存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設置。
解決辦法:
tomcat_home/bin下catalina.bat(win)或catalina.sh(linux)執(zhí)行代碼前加上:
set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m
=============================================================
eclipse java.lang.OutOfMemoryError: Java heap space 解決方案
===========================================================
eclipse java.lang.OutOfMemoryError: Java heap space 解決方案
eclipse 有啟動參數(shù)里設置jvm大小,因為eclipse運行時自己也需要jvm,所以eclipse.ini里設置的jvm大小不是具體某個程序運行時所用jvm的大小,這和具體程序運行的jvm大小無關。
那么怎么才能設置某個程序的jvm大小呢(當然控制臺運行的話不會存在這個問題,如:java -Xms256m -Xmx1024m classname,這樣就可以把當前程序的jvm大小給設定)?
因為eclipse里默認的一個程序的jvm配置為:-Xms8m -Xmx128m,所以我們的處理耗內(nèi)存比較大時需要手動調(diào)整一下,以便不會內(nèi)存溢出。具體的設置方法為:
選中被運行的類,點擊菜單‘Run as ->Open Run Dialog...’,選擇(x)=Argument標簽頁下的vm arguments框里輸入 -Xmx512m, 保存運行就ok了
=======================================================
Eclipse中java.lang.OutOfMemoryError: Java heap space
錯誤2007-06-12 11:53java.lang.OutOfMemoryError: Java heap space錯誤
在tomcat in的catalina.bat里加
set JAVA_OPTS=-Xms256m -Xmx512m -Djava.awt.headless=true
256和512分別是MIN和MAX內(nèi)存
在eclipse中的
windows->preferences..->tomcat->jvm..->jvm那一個文本框里,添加-Xms256m -Xmx512m
這樣就可以了!
==================================
Eclipse中VM設定方法 - [] - Tag:java.lang.OutOfMemoryError: Java heap space
點擊右鍵,選擇run...,彈出窗口如下圖,在vm輸入框中填寫合適的內(nèi)存值即可。
==================================
eclipse中,黃線是警示。
private Log log = LogFactory.getLog(AddCateAction.class);//小黃線在log上。
這里的黃線是指你定義了私有變量log,但沒有用到這個變量。
v.add(o); //這時eclipse下面出現(xiàn)了一個小黃線,表示仍然被引用?
這里是指add方法是不推薦的方法。
OutOfMemoryError和懷疑的引用沒有關系,可能是循環(huán)創(chuàng)建對象導致java內(nèi)存不足。
用參數(shù)指定java虛擬機的內(nèi)存.
java -Xms256m -Xmx1024m -XX:MaxPermSize=256M
========================================================
2、如果在啟動過程中出現(xiàn)內(nèi)存溢出問題,拋出類似如下異常信息:
java.lang.OutOfMemoryError: Java heap space
可以嘗試辦法:
A.修改Tomcat/bin/catalina.bat,添加如下內(nèi)容
set JAVA_OPTS=-Xms256m -Xmx512m -Djava.awt.headless=true [-XX:MaxPermSize=128M]
B.eclipse->windows->preferences..->tomcat->jvm..->jvm文本框里,添加-Xms256m -Xmx512m
C.eclipse->preference->java->instal jres->edit,增加參數(shù):-Xms256m -Xmx512m
參考原因:JVM中如果98%的時間是用于GC且可用的, Heap size不足2%的時候將拋出此異常信息。
JVM堆的設置是指java程序運行過程中JVM可以調(diào)配使用的內(nèi)存空間的設置.JVM在啟動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內(nèi)存的1/64,最大空間(-Xmx)是物理內(nèi)存的1/4。
可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設置。Heap Size 最大不要超過可用物理內(nèi)存的80%,一般的要將-Xms和-Xmx選項設置為相同,而-Xmn為1/4的-Xmx值。
Heap size的 -Xms -Xmn 設置不要超出物理內(nèi)存的大小。否則會提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。
==================================================================
我的問題原因:
使用Spring+Hibernate從數(shù)據(jù)庫中讀取大量數(shù)據(jù),使用了單例模式的AppContext的getBean,內(nèi)存中緩存了大量的Entity Bean……
目前仍沒有有效解決辦法,通過加大JVM內(nèi)存大小,以及修改數(shù)據(jù)讀取方式(如:只讀取有用信息)緩解了一下。
修改數(shù)據(jù)讀取方式:
例如一個EntityBean有如下字段:id, name, age, address, description。如果程序中只用到了此Bean的id和name字段,那么從數(shù)據(jù)庫中只用讀此兩字段,而不是讀取整個bean以及關聯(lián)的Bean。
java heap space
今天幫別人調(diào)bug,是一個讀取文件的程序,之前文件不大的時候沒出過這個錯誤,文件大了就出了
開始我以為是jvm內(nèi)存配置問題,但是配置到最大依然無效(就那個在jdk那里寫的一些參數(shù)-Xms200m -Xmx512m這兩個參數(shù)的設置不要超過物理內(nèi)存就可以了),百度搜索
java heap space 基本上都是告訴你這么做的,確實也能解決一部分問題。其實java heap space也確實是由兩種問題造成的。
1、jvm內(nèi)存分配太少
2、代碼有問題
我碰到的問題就是代碼有問題
錯誤代碼大概是
while((line=rd.readLine())!null){//這里報錯了
·····
······
······
DataMap d = new DataMap(XX,XX,XX);
list.add(d);
}
然后我覺得是這里的錯誤,改掉之后(add之后加一句d=null;并且把變量d的定義放外邊了。錯誤解決)
DataMap d ;
while((line=rd.readLine())!null){//這里報錯了
·····
······
······
d = new DataMap(XX,XX,XX);
list.add(d);
d = null;
}
這是一個典型的內(nèi)存溢出錯誤,溢出原因是list中放入對象的引用又沒有把變量手動置為空,這些變量就倒置了其對應的對象一直沒有釋放掉,一直消耗內(nèi)存。
我們知道java的GC會回收那些沒有被堆上的變量指向的對象(棧中的對象)。所以當你把d = null其實就是發(fā)出一個信號讓GC抽時間(注意是抽時間,不是立刻)
回收調(diào)上面new的對象。
http://itindex.net/detail/51440-java-%E5%86%85%E5%AD%98-%E6%BA%A2%E5%87%BA這篇文章整理了對java heap space錯誤的排查過程。大家可以看看。
這個錯誤得出的結論是
重復利用的變量放到外邊聲明,用過的對象及時的通知GC去回收。
還有就是推薦文章中提到的造成內(nèi)存溢出的問題要注意。
幫大家貼一下:
一)是否App中的類中和引用變量過多使用了Static修飾 如public staitc Student s;在類中的屬性中使用 static修飾的最好只用基本類型或字符串。如public static int i = 0; //public static String str;
二)是否App中使用了大量的遞歸或無限遞歸(遞歸中用到了大量的建新的對象)
三)是否App中使用了大量循環(huán)或死循環(huán)(循環(huán)中用到了大量的新建的對象)
四)檢查App中是否使用了向數(shù)據(jù)庫查詢所有記錄的方法。即一次性全部查詢的方法,如果數(shù)據(jù)量超過10萬多條了,就可能會造成內(nèi)存溢出。所以在查詢時應采用“分頁查詢”。
五)檢查是否有數(shù)組,List,Map中存放的是對象的引用而不是對象,因為這些引用會讓對應的對象不能被釋放。會大量存儲在內(nèi)存中。
六)檢查是否使用了“非字面量字符串進行+”的操作。因為String類的內(nèi)容是不可變的,每次運行"+"就會產(chǎn)生新的對象,如果過多會造成新String對象過多,從
而導致JVM沒有及時回收而出現(xiàn)內(nèi)存溢出。
最后當你發(fā)現(xiàn)這些問題都沒有但是依然出錯誤的時候,那么問題已經(jīng)不是代碼或者什么了。原因很可能是你操作的文件太大了,而是你要改變策略了。記得之前做個用poi
把表中的結果導入到excel表中,當數(shù)據(jù)集超過一定量的時候也會出現(xiàn)這種情況。你需要對操作對象做處理了。當時我們的處理是分頁一次拿出幾萬條分多次生成excel。。
所以面對這個問題分三步處理:
1.更改jvm內(nèi)存配置參數(shù)
2.查閱代碼找出很2的代碼
3.改變策略
第一種 環(huán)境myeclipse修改
在菜單window->preferecces.在JDK對話框中輸入-Xms512m -Xmx1024m這個參數(shù)就可以了。如圖:
第二種 tomcat安裝版修改方法:如圖:
第三種 tomcat綠色版修改方法。
在bin目錄下找到catalina.bat;在:gotHome后輸入
注意:內(nèi)存大小根據(jù)實際情況自己調(diào)整。
Xms Xmx PermSize MaxPermSize 區(qū)別
Eclipse崩潰,錯誤提示:
MyEclipse has detected that less than 5% of the 64MB of Perm
Gen (Non-heap memory) space remains. It is strongly recommended
that you exit and restart MyEclipse with new virtual machine memory
paramters to increase this memory. Failure to do so can result in
data loss. The recommended Eclipse memory parameters are:
eclipse.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
1.參數(shù)的含義
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
-vmargs 說明后面是VM的參數(shù),所以后面的其實都是JVM的參數(shù)了
-Xms128m JVM初始分配的堆內(nèi)存
-Xmx512m JVM最大允許分配的堆內(nèi)存,按需分配
-XX:PermSize=64M JVM初始分配的非堆內(nèi)存
-XX:MaxPermSize=128M JVM最大允許分配的非堆內(nèi)存,按需分配
我們首先了解一下JVM內(nèi)存管理的機制,然后再解釋每個參數(shù)代表的含義。
1)堆(Heap)和非堆(Non-heap)內(nèi)存
按照官方的說法:“Java 虛擬機具有一個堆,堆是運行時數(shù)據(jù)區(qū)域,所有類實例和數(shù)組的內(nèi)存均從此處分配。堆是在 Java 虛擬機啟動時創(chuàng)建的。”“在JVM中堆之外的內(nèi)存稱為非堆內(nèi)存(Non-heap memory)”。
可以看出JVM主要管理兩種類型的內(nèi)存:堆和非堆。簡單來說堆就是Java代碼可及的內(nèi)存,是留給開發(fā)人員使用的;非堆就是JVM留給自己用的,
所以方法區(qū)、JVM內(nèi)部處理或優(yōu)化所需的內(nèi)存(如JIT編譯后的代碼緩存)、每個類結構(如運行時常數(shù)池、字段和方法數(shù)據(jù))以及方法和構造方法的代碼都在非堆內(nèi)存中。
堆內(nèi)存分配
JVM初始分配的堆內(nèi)存由-Xms指定,默認是物理內(nèi)存的1/64;JVM最大分配的堆內(nèi)存由-Xmx指定,默認是物理內(nèi)存的1/4。默認空余堆內(nèi)存小于40%時,JVM就會增大堆直到-Xmx的最大限制;
空余堆內(nèi)存大于70%時,JVM會減少堆直到-Xms的最小限制。因此服務器一般設置-Xms、-Xmx 相等以避免在每次GC 后調(diào)整堆的大小。
說明:如果-Xmx 不指定或者指定偏小,應用可能會導致java.lang.OutOfMemory錯誤,此錯誤來自JVM,不是Throwable的,無法用try...catch捕捉。
非堆內(nèi)存分配
JVM使用-XX:PermSize設置非堆內(nèi)存初始值,默認是物理內(nèi)存的1/64;由XX:MaxPermSize設置最大非堆內(nèi)存的大小,默認是物理內(nèi)存的1/4。(還有一說:MaxPermSize缺省值和-server -client選項相關,
-server選項下默認MaxPermSize為64m,-client選項下默認MaxPermSize為32m。這個我沒有實驗。)
上面錯誤信息中的PermGen space的全稱是Permanent Generation space,是指內(nèi)存的永久保存區(qū)域。還沒有弄明白PermGen space是屬于非堆內(nèi)存,還是就是非堆內(nèi)存,但至少是屬于了。
XX:MaxPermSize設置過小會導致java.lang.OutOfMemoryError: PermGen space 就是內(nèi)存益出。
說說為什么會內(nèi)存益出:
(1)這一部分內(nèi)存用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區(qū)域,它和存放Instance的Heap區(qū)域不同。
(2)GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS 的話,就很可能出現(xiàn)PermGen space錯誤。
這種錯誤常見在web服務器對JSP進行pre compile的時候。
2)JVM內(nèi)存限制(最大值)
首先JVM內(nèi)存限制于實際的最大物理內(nèi)存,假設物理內(nèi)存無限大的話,JVM內(nèi)存的最大值跟操作系統(tǒng)有很大的關系。簡單的說就32位處理器雖然可控內(nèi)存空間有4GB,但是具體的操作系統(tǒng)會給一個限制,
這個限制一般是2GB-3GB(一般來說Windows系統(tǒng)下為1.5G-2G,Linux系統(tǒng)下為2G-3G),而64bit以上的處理器就不會有限制了。
2. 為什么有的機器我將-Xmx和-XX:MaxPermSize都設置為512M之后Eclipse可以啟動,而有些機器無法啟動?
通過上面對JVM內(nèi)存管理的介紹我們已經(jīng)了解到JVM內(nèi)存包含兩種:堆內(nèi)存和非堆內(nèi)存,另外JVM最大內(nèi)存首先取決于實際的物理內(nèi)存和操作系統(tǒng)。所以說設置VM參數(shù)導致程序無法啟動主要有以下幾種原因:
1) 參數(shù)中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;
2) -Xmx的值和-XX:MaxPermSize的總和超過了JVM內(nèi)存的最大限制,比如當前操作系統(tǒng)最大內(nèi)存限制,或者實際的物理內(nèi)存等等。說到實際物理內(nèi)存這里需要說明一點的是,
如果你的內(nèi)存是1024MB,但實際系統(tǒng)中用到的并不可能是1024MB,因為有一部分被硬件占用了。
3. 為何將上面的參數(shù)寫入到eclipse.ini文件Eclipse沒有執(zhí)行對應的設置?
那為什么同樣的參數(shù)在快捷方式或者命令行中有效而在eclipse.ini文件中是無效的呢?這是因為我們沒有遵守eclipse.ini文件的設置規(guī)則:
參數(shù)形如“項 值”這種形式,中間有空格的需要換行書寫,如果值中有空格的需要用雙引號包括起來。比如我們使用-vm C:/Java/jre1.6.0/bin/javaw.exe參數(shù)設置虛擬機,
在eclipse.ini文件中要寫成這樣:
-vm
C:/Java/jre1.6.0/bin/javaw.exe
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M
實際運行的結果可以通過Eclipse中“Help”-“About Eclipse SDK”窗口里面的“Configuration Details”按鈕進行查看。
另外需要說明的是,Eclipse壓縮包中自帶的eclipse.ini文件內(nèi)容是這樣的:
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
其中–launcher.XXMaxPermSize(注意最前面是兩個連接線)跟-XX:MaxPermSize參數(shù)的含義基本是一樣的,我覺得唯一的區(qū)別就是前者是eclipse.exe啟動的時候設置的參數(shù),
而后者是eclipse所使用的JVM中的參數(shù)。其實二者設置一個就可以了,所以這里可以把–launcher.XXMaxPermSize和下一行使用#注釋掉。
4. 其他的啟動參數(shù)。 如果你有一個雙核的CPU,也許可以嘗試這個參數(shù):
-XX:+UseParallelGC
讓GC可以更快的執(zhí)行。(只是JDK 5里對GC新增加的參數(shù))
補充:
如果你的WEB APP下都用了大量的第三方jar,其大小超過了服務器jvm默認的大小,那么就會產(chǎn)生內(nèi)存益出問題了。
解決方法: 設置MaxPermSize大小
可以在myelipse里選中相應的服務器比如tomcat5,展開里面的JDK子項頁面,來增加服務器啟動的JVM參數(shù)設置:
-Xms128m
-Xmx256m
-XX:PermSize=128M
-XX:MaxNewSize=256m
-XX:MaxPermSize=256m
或者手動設置MaxPermSize大小,比如tomcat,
修改TOMCAT_HOME/bin/catalina.bat,在echo "Using CATALINA_BASE: $CATALINA_BASE"上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
建議:將相同的第三方jar文件移置到tomcat/shared/lib目錄下,這樣可以減少jar 文檔重復占用內(nèi)存
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答!! 點擊進入論壇