工作中雖然不經(jīng)常遇到j(luò)ava.lang.OutOfMemoryError: Java heap space老客,但一旦出現(xiàn)將會(huì)嚴(yán)重影響系統(tǒng)運(yùn)行玻淑,如果不能迅速解決族壳,將會(huì)帶來(lái)很惡劣的影響孔庭,所以掌握OutOfMemoryError:Java heap space的解決方法也是非常有必要的梳侨。
解決問(wèn)題首先要找出原因蛉威,要找原因要有依據(jù),而內(nèi)存溢出時(shí)的堆dump信息是最為重要的依據(jù)之一
步驟一:先保證能拿到堆dump信息
我寫(xiě)了一個(gè)簡(jiǎn)單的小例子走哺,jvm運(yùn)行參數(shù)為:-Xmx20M -Xms20M -XX:+HeapDumpOnOutOfMemoryError
程序執(zhí)行后很快就會(huì)拋出內(nèi)存溢出錯(cuò)誤
其實(shí)通過(guò)異常信息基本已經(jīng)可以鎖定內(nèi)存溢出原因蚯嫌,但為了解決問(wèn)題思路具有通用性,我們繼續(xù)往下看
步驟二:分析堆內(nèi)存溢出時(shí)的dump文件
堆dump文件可以直接下載我的dump文件丙躏,用Eclipse Memory Analyzer或者VisualVM打開(kāi)齐帚,我用的是Eclipse Memory Analyzer
可以看到這兩個(gè)線程占的內(nèi)存總量達(dá)到了近90%
再進(jìn)一步展開(kāi)Thread-2的堆信息
可以看到有大量的byte數(shù)組,就是我們代碼中新建的數(shù)組彼哼,正是因?yàn)檫@個(gè)原因?qū)е聝?nèi)存溢出对妄。當(dāng)然在實(shí)際業(yè)務(wù)代碼中能看到具體的業(yè)務(wù)類(lèi)名稱(chēng),基本上就一目了然了敢朱。
步驟三:如果堆dump信息也正常怎么辦剪菱?
可能經(jīng)過(guò)上面兩個(gè)步驟的分析摩瞎,雖然確實(shí)由于堆中對(duì)象太多導(dǎo)致內(nèi)存溢出,但都是正常的對(duì)象孝常,沒(méi)有某個(gè)類(lèi)的對(duì)象產(chǎn)生特別多的情況旗们,應(yīng)該怎么辦?
這時(shí)候就考慮增大堆內(nèi)存的大小构灸,或者減少對(duì)象的產(chǎn)生
方法1:直接增加堆內(nèi)存大小上渴,調(diào)整-Xmx -Xms 的大小
方法2:本地緩存改為集中緩存。大量使用本地緩存(如大量使用HashMap作為K/V緩存)喜颁,會(huì)占用堆上很多內(nèi)存稠氮,尤其在集群情況下,會(huì)造成更多浪費(fèi)半开,這時(shí)可以考慮把本地緩存改為集中緩存(如Redis)隔披。
方法3:考慮優(yōu)化代碼,看是否有優(yōu)化的空間寂拆。