系统相关
首页 > 系统相关> > jvm中jmap+MAT内存溢出实战(四)

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