jmap MAT内存溢出实践
jmap MAT内存溢出实践
一、创建Spring Boot工程
进入https://start.spring.io/网站,配置如下图
点击创建工程,然后用Idea或者Eclipse打开
二、创建模拟Heap内存溢出的代码
1、创建MemoryController类
2、创建User类
public class User {
private int id;
private String name; public User(int id, String name) {
this.id = id;
this.name = name;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
3、 设置最大内存和最小内存为32M
-Xmx32M -Xms32M
4、运行工程
http://127.0.0.1:8080/heap
出现内存溢出
三、创建模拟非Heap内存溢出
1、引入asm
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
2、创建Metaspace类
/**
* https://blog.csdn.net/bolg_hero/article/details/78189621
* 继承ClassLoader是为了方便调用defineClass方法,因为该方法的定义为protected
*/
public class Metaspace extends ClassLoader{ public static List<Class<?>> createClasses() {
// 类持有
List<Class<?>> classes = new ArrayList<Class<?>>();
// 循环1000w次生成1000w个不同的类。
for (int i = 0; i < 10000000; ++i) {
ClassWriter cw = new ClassWriter(0);
// 定义一个类名称为Class{i},它的访问域为public,父类为java.lang.Object,不实现任何接口
cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,
"java/lang/Object", null);
// 定义构造函数<init>方法
MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
"()V", null, null);
// 第一个指令为加载this
mw.visitVarInsn(Opcodes.ALOAD, 0);
// 第二个指令为调用父类Object的构造函数
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
"<init>", "()V", false);
// 第三条指令为return
mw.visitInsn(Opcodes.RETURN);
mw.visitMaxs(1, 1);
mw.visitEnd(); Metaspace test = new Metaspace();
byte[] code = cw.toByteArray();
// 定义类
Class<?> exampleClass = test.defineClass("Class" + i, code, 0, code.length);
classes.add(exampleClass);
}
return classes;
} }
3、创建调用方式
private List<Class<?>> classList = new ArrayList<>();
/**
* -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
*
* @return
*/
@GetMapping("/nonheap")
public String nonheap(){
while (true){
classList.addAll(Metaspace.createClasses());
}
}
4、设置JVM参数
-XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
5、启动调用
http://127.0.0.1:8080/nonheap
发现内存溢出
Exception in thread "http-nio-8080-exec-4" java.lang.OutOfMemoryError: Metaspace
四、解决方法
如果生成环境出现内存溢出,应该如何解决呢
1、导出内存映像文件
1)内存溢出自动导出
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
配置如下
-Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
然后调用http://localhost:8080/heap
显示hprof文件已经生成了
2)使用jmap命令手动导出
jmap -dump:format=b,file=heap.hprof 15296
15296是tomcat的进程。 这样就生成了一个heap.hprof 文件
jmap -heap 5579 查看内存的使用,每个区块占有多少内存(5579是tomcat的进程)
2、MAT分析内存映像文件
现在MAT工具 http://www.eclipse.org/mat/downloads.php
我这里下载的是Windows (x86_64)版本
然后使用这个工具打开刚才生成的hprof文件
最新文章
- Android开发过程遇到的问题小计
- Swift—泛型(上)
- 帝国cms栏目自定义字段首页调用
- Nginx中的rewrite指令
- 《Focus On 3D Terrain Programming》中一段代码的注释三
- AI线性图标教程-转起
- hdu 3966 树链剖分
- sharepoint 使用命令行注册dll文件到gac的方法
- [html5] 学习笔记-服务器推送事件
- 关于log4.net 错误,求解
- python基础教程(十)
- JAVA_SE基础——61.字符串入门
- windows根据端口号杀进程
- hexo基本操作
- Ubuntu16.04 启动纯文本界面方法
- 【工具向01】——markdown 文本编辑语言相关
- ES6之Promise用法详解
- cocos2d-x 真正的定时器之schedule
- Artistic Style在windows下的使用(C/C++)
- Postgres客户端编码问题