hprof文件分析工具_【赵强老师】如何分析Java的内存溢出问题
歡迎關(guān)注趙強(qiáng)老師微信公眾號:myitshare
一、什么是內(nèi)存溢出?
內(nèi)存溢出(OOM:out of memory)通俗理解就是內(nèi)存不夠,通常在運(yùn)行大型軟件或游戲時(shí),軟件或游戲所需要的內(nèi)存遠(yuǎn)遠(yuǎn)超出了你主機(jī)內(nèi)安裝的內(nèi)存所承受大小,就叫內(nèi)存溢出。
在Java中,將會(huì)產(chǎn)生java.lang.OutOfMemoryError??聪玛P(guān)于的官方說明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是說,當(dāng)JVM因?yàn)闆]有足夠的內(nèi)存來為對象分配空間并且垃圾回收器也已經(jīng)沒有空間可回收時(shí),就會(huì)拋出這個(gè)error(注:非exception,因?yàn)檫@個(gè)問題已經(jīng)嚴(yán)重到不足以被應(yīng)用處理)。
二、為什么產(chǎn)生OOM?
為什么會(huì)沒有內(nèi)存了呢?原因不外乎有兩點(diǎn):
- 分配的少了:比如虛擬機(jī)本身可使用的內(nèi)存(一般通過啟動(dòng)時(shí)的VM參數(shù)指定)太少。
- 應(yīng)用用的太多,并且用完沒釋放,浪費(fèi)了。此時(shí)就會(huì)造成內(nèi)存泄露或者內(nèi)存溢出。
在Java語言中,由于存在了垃圾自動(dòng)回收機(jī)制,所以,我們一般不用去主動(dòng)釋放不用的對象所占的內(nèi)存,也就是理論上來說,是不會(huì)存在“內(nèi)存泄露”的。但是,如果編碼不當(dāng),比如,將某個(gè)對象的引用放到了全局的Map中,雖然方法結(jié)束了,但是由于垃圾回收器會(huì)根據(jù)對象的引用情況來回收內(nèi)存,導(dǎo)致該對象不能被及時(shí)的回收。如果該種情況出現(xiàn)次數(shù)多了,就會(huì)導(dǎo)致內(nèi)存溢出,比如系統(tǒng)中經(jīng)常使用的緩存機(jī)制。Java中的內(nèi)存泄露,不同于C++中的忘了delete,往往是邏輯上的原因泄露。
三、如何分析Java OOM?
在故障定位(尤其是out of memory)和性能分析的時(shí)候,經(jīng)常會(huì)用到一些文件來幫助我們排除代碼問題。這些文件記錄了JVM運(yùn)行期間的內(nèi)存占用、線程執(zhí)行等情況,這就是我們常說的dump文件。常用的有heap dump和thread dump(也叫javacore,或java dump)。我們可以這么理解:heap dump記錄內(nèi)存信息的,thread dump是記錄CPU信息的。這里我們重點(diǎn)介紹heap dump。
heap dump文件是一個(gè)二進(jìn)制文件,它保存了某一時(shí)刻JVM堆中對象使用情況。HeapDump文件是指定時(shí)刻的Java堆棧的快照,是一種鏡像文件。Heap Analyzer工具通過分析HeapDump文件,哪些對象占用了太多的堆棧空間,來發(fā)現(xiàn)導(dǎo)致內(nèi)存泄露或者可能引起內(nèi)存泄露的對象。
四、案例
首先,我們來開發(fā)一段Java程序。
import java.util.*;public class Test {public static void main(String[] args) {List<String> list = new ArrayList<String>();int i = 0;while (true) {list.add(new String("test")); }}}使用下面的命令運(yùn)行該程序時(shí)設(shè)置JVM的堆內(nèi)存(heap size)的極限值為10M(-Xmx10m)。
java -Xmx10m Test很快,程序?qū)?huì)產(chǎn)生OOM的錯(cuò)誤,如下圖所示:
五、如何生成Head Dump文件?
我們可以在運(yùn)行Java程序的時(shí)候,加入下面的參數(shù):
-XX:+HeapDumpOnOutOfMemoryError此參數(shù)是幫助生成dump文件,程序啟動(dòng)后直到拋出OOM異常。異常拋出后,在程序的classpath下會(huì)生成以一個(gè)以.hprof結(jié)尾的文件,如:java_pid4504.hprof,這就是我們需要的dump文件。
如下圖所示:
六、使用IBM heapAnalyzer分析Head Dump文件
IBM heapAnalyzer(https://www.ibm.com/support/pages/ibm-heapanalyzer)是IBM開發(fā)的強(qiáng)大的內(nèi)存dump分析工具,,IBM heapAnalyzer是通過分析OOM后的Java heap dump文件的,通過對dump文件的分析找到內(nèi)存可能泄露的點(diǎn)。
啟動(dòng)IBM heapAnalyzer,并導(dǎo)入剛才生成的Heap Dump文件,如下圖所示。
通過分析我們會(huì)發(fā)現(xiàn),系統(tǒng)94.19%的內(nèi)存都被一個(gè)ArrayList占用了(里面保存的都是Object)。這里就有可能是一個(gè)內(nèi)存的溢出點(diǎn)。當(dāng)然,我們這個(gè)例子非常典型,在實(shí)際工作可能沒有這么明顯,需要具體問題具體分析。
總結(jié)
以上是生活随笔為你收集整理的hprof文件分析工具_【赵强老师】如何分析Java的内存溢出问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: i7 3820 2400内存超频实测:性
- 下一篇: concurrent 底层_万字长文!从