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文件

最新文章

  1. Android开发过程遇到的问题小计
  2. Swift—泛型(上)
  3. 帝国cms栏目自定义字段首页调用
  4. Nginx中的rewrite指令
  5. 《Focus On 3D Terrain Programming》中一段代码的注释三
  6. AI线性图标教程-转起
  7. hdu 3966 树链剖分
  8. sharepoint 使用命令行注册dll文件到gac的方法
  9. [html5] 学习笔记-服务器推送事件
  10. 关于log4.net 错误,求解
  11. python基础教程(十)
  12. JAVA_SE基础——61.字符串入门
  13. windows根据端口号杀进程
  14. hexo基本操作
  15. Ubuntu16.04 启动纯文本界面方法
  16. 【工具向01】——markdown 文本编辑语言相关
  17. ES6之Promise用法详解
  18. cocos2d-x 真正的定时器之schedule
  19. Artistic Style在windows下的使用(C/C++)
  20. Postgres客户端编码问题

热门文章

  1. 【转】Delphi XE10 Android Splash设备自适应和沉浸式状态条
  2. 获取页面元素的css属性
  3. 【Python】练习题
  4. Android 1.5-7.0(持续更新)安全机制一览
  5. 【leetcode】13-Roman2Integer
  6. Java栈的简单实现
  7. Unity射线检测的用法总结
  8. window.location.herf=url参数有中文,到后台乱码问题解决
  9. Linux配置浮动IP
  10. MySql NDB cluster replication配置