jvm中jmap+MAT内存溢出实战(四)
作者:互联网
一、内存溢出
1.堆内存溢出
堆内存中保存着对象,所以只要不停的往集合中存放对象,同时让gc不去回收对象,堆内存就会被撑爆。为了避免被gc回收,所以在一个方法中创建所以堆对象。
package com.jvm;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
List<User> users=new ArrayList<User>();
while(true) {
users.add(new User("aa",12));
}
}
}
class User{
public String name;
public int age;
public User(String name,int age) {
this.name=name;
this.age=age;
}
}
为了缩短看见堆内存溢出异常的时间,启动时需要设置一下堆内存大小,如果使用的是eclipse,可以右键Run As-->Run configrations
点击argument;在vm argument窗口中写入: -Xms12m -Xmx12m
设置初始化堆大小12M,堆最大内存12M.
结果:
2.非堆内存溢出
非堆内存主要存在着Method,class的等文件信息。所以我们需要动态创建.class文件。
二、导出内存映像文件
1.参数
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
./:是路径,可以写绝对路径。
在添加jvm参数的窗口vm argument中加入上面两个参数。两个参数之间用空格隔开。
2.运行结果
3.在参数中写的路径下查找
会发现生成了一个以.hprof结尾的文件,这就是内存映像文件。
三、文件分析
1.安装MAT
可以在eclipse安装MAT的插件,也可以自行下载,为一个新的进程启动。
2.倒入.hprof
用MAT将我们生产的.hprof文件打开。
打开之后如图所示:
3.我们现在处于的overview窗口。
下面有三个:Action Reports Step By Step
我们点击报告Reports下面的Leak Suspects(怀疑溢出)
有a,b两块,Problem Suspect 1 (怀疑a块有问题)
占用了95%的空间。点开Details
列出了a模块的所以对象:com.jvm.User
从图可以看出内存溢出的主要原因是com.jvm.User类过多导致的。
四、jmap
1.上面设置jvm参数只能在堆内存溢出的时候才导出内存映像文件,但是很多时候我们需要在内存溢出之前(程序运行过程中)导出
jps 查看进程pid
jmap -dump:format=b,file=heap.hprof 23530
会在当前目录下生成一个heap.hprof的文件
使用jamp,可以在程序运行过程中随时到处内存映像文件
五、总结
堆内存溢出,一般情况下是对象过多,而对象又root可达,无法被GC回收,导致堆内存溢出。
标签:文件,MAT,hprof,内存,jvm,jmap,public,溢出 来源: https://blog.csdn.net/qq_35151346/article/details/100187555