JAVA 堆設置
堆已經講得差不多啦,這章我們以一個例子來說說如何設置以及當發生堆溢出的時候怎么排查問題。先看一小段代碼:

代碼中使用了一個無限循環來為list添加對象,如果采用默認的堆大小的話可能要等待好久才能出現堆溢出的錯誤,因此我們要將其設置小一點:
-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError,elipse中的設置方法我們在第一章講過了,這里不多說啦。-Xms10m,意思就是堆的最小內存為10m。同理-Xmx10m的意思就是最大內存也為10m。這兩個都是設置為10m,那么堆的大小就是10m。而-XX:+HeapDumpOnOutOfMemoryError指的是當發生內存溢出的時候會將當前的內存使用情況生成一個快照保存起來,但需要eclipse下載一個MAT的插件,下載方式度娘到處都是。
使用剛剛設置的參數啟動程序,稍等一小會就會出現以下錯誤:

顯示出堆溢出錯誤,並且生成了一個叫做java_pid4792.hprof的文件,我們刷新項目便可以看到該文件,雙擊打開,需要一段的加載時間。

首先可以看到的是一個餅狀圖,占用部分最大的便是發生溢出錯誤的部分,我們接着往下看 :
我們這里看看畫紅線的部分,這里列出一些存活的大對象,在溢出的時候一般先懷疑大對象,我們點進去:

這里列出占用內存最大的幾個對象,很顯然,第一個很可疑,占用率達到了94.64%!繼續跟進:

發現都是test對象,因此排查的時候可以從這個方面下手。接着我們右鍵該對象選擇Path To GC Root(在引用鏈上的路徑),再選擇exclue all phantom/weak/soft etc. reference ,結果如圖:

可以看到他是被List引用了,因此一直在引用鏈上,導致無法被回收掉,也就出現了內存溢出。
本文只講了MAT的一個最基本的用途,指出排查思路,感興趣的小伙伴可以結合工作上的案例自己深入的去了解其更多的用途。
關於堆中各個區域的設置先不在這里講,一步一步來,等道路明朗了,問題也就都迎刃而解了!
