在查看內存溢出的時候,我們需要明白,堆溢出和持久代溢出,他們不一樣,說到內存泄漏,我們就需要明白,內存中 年老代和新生代,和持久代,這3塊的數據
自己的理解:
new了一個對象,會進入到堆里面,先放到年輕代中 也就是new generation ,他放到eden中,如果eden滿了,就會進行一次yong gc ,如果還有存活對象(被用到的對象)就會被移到S0區或者S1中轉移,如果s0和S1都已經滿了,那么這些對象(引用)就會把放到年老代中去,也就是old generation 區,
如果old區,也滿了,也會GC一次,也就是FGC,也就是fullGC,如果fullGC一次,就在也不接受新new的對象,往里面存儲3如果fullGC,5分鍾拒絕服務,jvm拒絕工作,那么5分鍾類都沒辦法使用,所以fullGC時間要短,次數要少。
持久代:當perm里面滿了,也會存在fgc,在perm里面存儲的是類對象
如果還沒有不懂內存溢出,大家應該懂這個現象:超時,不進行服務,服務掛掉,接口不在服務這樣的異常問題,這樣的問題可能是內存溢出造成的。
1.制造內存泄漏的代碼
import java.util.ArrayList; import java.util.List; public class test2 { public static void main(String[] args) { int size=1024 * 1024 *8; #1MB=1024KB=1024*1024B=1024*1024*8b List<byte[] > list =new ArrayList<byte[]>(); for (int i=0;i<1024;i++){ System.out.println("JVM 寫入數據"+(i+1)+"M"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } list.add(new byte[size]); #每一秒就往堆中寫入一個數據 } } }
2.使用jdk 自帶的工具 jvisualvm.exe 查看內存泄漏
我工具的存放路徑為:C:\Program Files (x86)\Java\jdk1.8.0_131\bin
執行我的程序,查看visual GC
你會發現eden中數據,然后慢慢的移動到old,
當你內存泄漏了,old 也就滿了,在監視中也可以看到,看到堆是一個階梯式上升,因為我們程序就是每次都往堆中放入1M的數據,直至它內存滿
我們點擊“堆dump” ,就會生成一個 hpro文件,我們可以對hpro文件進行分析,分析見下一篇文章 《https://www.cnblogs.com/chongyou/p/11710339.html》
程序中,我的是在寫入179M就會內存溢出,
如果發現自己沒有visual GC,那需要去安裝插件,
在可用插件中找到visual GC,因為我已經安裝了,所以在已安裝中