問題描述
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
解決方案[轉(zhuǎn)]
一直都知道可以設(shè)置jvm heap大小,一直用eclipse寫/調(diào)試java程序。一直用命令行or console加參數(shù)跑程序。現(xiàn)象:在eclipse的配置文件eclipse.ini中設(shè)置-vmargs -Xms500m -Xmx1024m,在eclipse中直接run 或者debug某些耗內(nèi)存的程序時(shí)依然出現(xiàn)java.lang.OutOfMemoryError: Java Heap Space錯(cuò)誤,即通常認(rèn)為的內(nèi)存不足,java虛擬機(jī)內(nèi)存不夠用。而在命令行加這些參數(shù)則有效果,不會(huì)出錯(cuò)。這說(shuō)明一個(gè)問題,這些參數(shù)根本沒有起作用。今天需要在eclipse里調(diào)試程序,還沒到需要調(diào)試的地方就heap error了,在網(wǎng)上搜了很多地方,得到了最終的答案:
選中被運(yùn)行的類,點(diǎn)擊菜單‘run->run...’,選擇(x)=Argument標(biāo)簽頁(yè)下的vm arguments框里
輸入 -Xmx800m, 保存運(yùn)行。
原來(lái)還需要對(duì)每個(gè)project單獨(dú)設(shè)置,汗...
有三種可能導(dǎo)致OutOfMemoryError。首先是,此JVM有真實(shí)的內(nèi)存泄漏,導(dǎo)致此JVM堆在內(nèi)部實(shí)現(xiàn)時(shí)產(chǎn)生了一個(gè)Bug。這極不可靠。所有JVM都經(jīng)過(guò)充分的測(cè)試,并且,如果有人發(fā)現(xiàn)這種bug,它將絕對(duì)是最高的優(yōu)先級(jí)。因此你可以非常寬心地排除這種可能性。
第二種可能的OutOfMemoryError原因只不過(guò)是,你沒有為你的應(yīng)用程序運(yùn)行時(shí)給予足夠多的可用內(nèi)存。這種情況,有兩種可能的方案,或者增加 JVM堆可用大小,或者減少你的應(yīng)用程序所需的內(nèi)存總量。提高JVM可用堆大小可以簡(jiǎn)單的使用JVM的 -Xmx 參數(shù)。假如你將此參數(shù)設(shè)置盡可能的大(可用內(nèi)存極限不要超過(guò)系統(tǒng)物理內(nèi)存,否則你的應(yīng)用程序?qū)⒎猪?yè)并暫停),仍然有以上所提到的內(nèi)存問題,那么,你需要減 少你的應(yīng)用程序所可能用到內(nèi)存總量。減少應(yīng)用程序內(nèi)存可能是簡(jiǎn)單的,你可能允許一些集合過(guò)大,例如使用了許多大的緩沖區(qū)?;蛘咚^(guò)于復(fù)雜,要求你重新實(shí)現(xiàn) 一些類,乃至重新設(shè)計(jì)應(yīng)用程序。
讀者 Jams Stauffer 指出有些JVM(例如 sun的 JVMs),還有一個(gè)“Perm”參數(shù)用來(lái)處理JVM結(jié)構(gòu)與類對(duì)象。如果你正在使用一個(gè)數(shù)量非常巨大的類集,它有可能運(yùn)行在"Perm"空間之外,然后你 需要增加此空間的大小,例如,sun的JVM使用 -XX:PermSize 與 -XX:MaxPermSize 選項(xiàng)。
第三種導(dǎo)致OutOfMemoryError最為常見,無(wú)心的對(duì)象引用保持。你沒有明確無(wú)誤的釋放對(duì)象,以致于你的堆增長(zhǎng)再增長(zhǎng),直到你沒有額外的空間。
處理OutOfMemoryError:
是JVM內(nèi)部的BUG?不太可能。如果是,這是優(yōu)先級(jí)最高的BUG(為什么還沒有人發(fā)現(xiàn)它,而你碰到了?)。
沒有足夠的內(nèi)存分配給實(shí)際運(yùn)行的應(yīng)用程序??jī)煞N選擇:使用-Xmx參數(shù)增加堆的最大使用內(nèi)存(或者使用-XX:MaxPermSize參數(shù)增加Perm空 間大小); 或者使用更小的集合/緩沖區(qū)/表空間/對(duì)象.....,以減少所需要的內(nèi)存總量,也就是說(shuō),可以調(diào)整對(duì)象大小,重新設(shè)計(jì)與重新實(shí)現(xiàn)你的應(yīng)用程 序。
無(wú)心的對(duì)象引用保持?找到保持這些無(wú)意引用的源對(duì)象,改變它并釋放這些對(duì)象。在IBM開發(fā)者社區(qū)的文章綱要式的揭示了這樣一個(gè)通用的處理過(guò)程。這個(gè)過(guò)程主 要是等到應(yīng)用程序到達(dá)恒定狀態(tài)--你將期望最多的新創(chuàng)建的對(duì)象是臨時(shí)對(duì)象,并且可以被垃圾收集器收集。這常常是在應(yīng)用程序所有的初始化工作完成之后。
強(qiáng)迫垃圾收集,獲得一個(gè)堆的對(duì)象快照。
做任何工作可能正在導(dǎo)到無(wú)意的對(duì)象引用保持。
強(qiáng)迫另一次垃圾收集并獲得第二次堆的對(duì)象快照。
比較這兩個(gè)快照,觀察從第一個(gè)快照到第二個(gè)快照哪些對(duì)象在數(shù)量上有所增加。因?yàn)槟阍诳煺罩皬?qiáng)迫垃圾收集,剩下的將是所有被應(yīng)用程序引用的對(duì)象,比較兩個(gè)快照將準(zhǔn)確的標(biāo)識(shí)那些新創(chuàng)建的、保留在應(yīng)用程序里的對(duì)象。
根據(jù)你對(duì)應(yīng)用程序的認(rèn)識(shí),決定兩個(gè)快照比較中,哪些對(duì)象正在無(wú)意的保持對(duì)象引用。
跟蹤前導(dǎo)引用,找到哪些對(duì)象正在引用這些無(wú)意的保持對(duì)象,直到你找到導(dǎo)致此問題的源對(duì)象
啟動(dòng)虛擬機(jī)的時(shí)候,加上一個(gè)參數(shù):-Xms800m -Xmx800m就好了
-Xms <size>
設(shè)置JVM初始化堆內(nèi)存大小
-Xmx <size>
設(shè)置JVM最大的堆內(nèi)存大小
如果是應(yīng)用程序,則:java -Xms800m -Xmx800m 你的類名
如果是tomcat之類的web服務(wù)器,在這個(gè)服務(wù)器的啟動(dòng)文件后面加上這個(gè)參數(shù)即可。
另外設(shè)置環(huán)境變量
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "
參考來(lái)源
http://hi.baidu.com/dearfenix/blog/item/1b0ce80e64ca12ce7bcbe109.html
http://hi.baidu.com/%C2%ED%D3%C0/blog/item/90d9e5033663118bd43f7c2a.html
http://www.chq.name/content/view/306_2.html