当运行如下代码后,可以看到,堆内存逐渐减少,cpu使用率逐渐变高然后控制台报错(见最下面)
package com.jvm.test;
import java.util.ArrayList;
import java.util.List;public class Test {
public static void main(String[] args) {
List<Demo> demoList = new ArrayList<Demo>();
while(true){
demoList.add(new Demo());
}
}
}
那么一个大的项目的话,要如何定位呢?
我们需要使用分析工具,在使用工具之前,要把堆内存转储成一个快照?
1.生成快照
右键run as --》 runcondifurations 在VM arguments里加 -XX:+HeapDumpOnOutOfMemoryError,再一次执行就会发现控制台报错前面多了,然后项目文件夹里多了个文件
对了,测试时有没发现要等很久才报错,就在后面加设置堆内存的参数-Xms20m -Xmx20m如下( 是不是很熟悉,最初内存溢出百度就是要你加这个吧,意思是堆初始内存为20m,最大也为20m)
这次会发现很快就报错了,因为堆内存变小,内存溢出也就变快了,打开快照文件发现都是乱码,所以我们要下载工具啦
2.下载java memory analyzer
下载链接点这,我的是64位的,根据你的操作系统选择后下载
下载完成后点击exe文件打开(跟打开eclipse一样慢...)
打开之后file --》 open heap dump --》选择你之前生成的快照文件
--》finish,可看到如下界面
看到这个图片你可能不知道啥意思,那么再点击这个,
Shallow Heap:当前对象占堆内存大小,Retained Heap:该对象引用的所有对象占堆内存大小 Percentage:百分比
再看左下角,发现问题所在了吧,堆内存溢出就是因为存储了太多demo类对象
3.解决内存溢出问题
利用分析工具定位问题后,发现原因后解决方法一般有这点
(1)就像我这里,代码问题,修改代码
(2)堆内存设置太小,代码没问题,把jvm参数设置里把堆内存设置大点-Xms20m -Xmx20m(自己改值)
(3)物理内存小了,想办法扩张物理内存,加内存条或者...