jvm內存溢出問題的定位方法


jvm內存溢出問題的定位方法

今天給大家帶來JVM體驗之內存溢出問題的定位方法。
廢話不多說直接開始:

一、Java堆溢出

測試代碼如下:

import java.util.*;
public class A {
	public static void main(String[] args) {
		List<String> strList = new ArrayList<>();
		while(true) {
			strList.add("");
		}
	}
}

運行過程如下所示:

我們在這里可以看到內存在不斷的上漲,而Java在到一定時候會爆出OOM異常。
如下:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:265)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
at java.util.ArrayList.add(ArrayList.java:462)
at A.A.main(A.java:9)

現在程序是很簡單,不過如果在大型項目里爆了堆溢出可就麻煩了。
我們很難通過代碼定位。
所以我們需要用工具對其分析。


二、堆內存快照

我們先對Eclipse進行運行配置。


參數如下所示
-XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m
運行結果如下:

隨后我們找到項目地址,我們會發現在Project本目錄中出現了個hprof文件


至此我們就把堆內存快照保存下來了。


三、分析

我們這里需要一個工具叫MAT是Eclipse提供的分析工具。

這里是鏈接我們選擇清華的鏡像

https://mirrors.tuna.tsinghua.edu.cn/eclipse/mat/1.9.0/rcp/MemoryAnalyzer-1.9.0.20190605-win32.win32.x86_64.zip

解壓后運行

這里運行會很慢,需要等待很久。打開后如下所示。

用這個工具把我們之前dump下來的東西放進去

點開dominator_tree,我們會發現問題儲在main線程里,


這里有倆參數,一個是Shallow Heap,另一個是Retained Heap

shallowHeap Retained Heap
對象本身占用的內存大小 對象本身占用的大小+對象引用的大小總和

常規理解就是如果我們對其做GC,那么就會釋放掉這么大的內存。

而其中的這個Object對象就是我們之前創建的String類

至此我們就完成了對內存錯誤的定位。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM