内存溢出问题定位

23 篇文章 1 订阅
3 篇文章 0 订阅

内存溢出问题定位

前言:内存溢出是程序运行中很常见的一个问题,导致这个问题发生的可能性也有很多,如内存分配不足或者内存泄漏等,如何定位到问题所在是非常重要的,至此记录一下关于定位内存溢出问题的方法与思路。(在实验过程出现了一个关于maven版本冲突的问题:解决链接
主要工具:jmap、mat工具

步骤:

  • 先写出两个demo代码:一个不断创建对象导致堆内存溢出,一个不断创建类导致元空间内存溢出。
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MemoryController {
	
	private List<User>  userList = new ArrayList<User>();
	private List<Class<?>>  classList = new ArrayList<Class<?>>();
	
	/**
	 * 设置堆内存大小
	 * -Xmx32M -Xms32M
	 * */
	@GetMapping("/heap")
	public String heap() {
		int i=0;
		while(true) {//这里的User是一个随便创建的类
			userList.add(new User(i++, UUID.randomUUID().toString()));
		}
	}
	
	
	/**设置元空间内存大小
	 * -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M
	 * */
	@GetMapping("/nonheap")
	public String nonheap() {
		while(true) {//关于此方法的详细代码在我关于maven版本冲突博客中
			classList.addAll(Metaspace.createClasses());
		}
	}
	
}
  • 运行程序,在VM参数上设置堆内存大小为32M
    在这里插入图片描述
  • 访问网址/heap路径运行测试代码,出现java.lang.OutOfMemoryError: GC overhead limit exceeded的异常。
  • 导出内存映像文件(两种方法)
    1、VM参数方法:内存溢出自动导出
//设置自动导出以及导出到当前路径
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./

2、jmap命令:先运行对应的jar进程,jps找到该进程ID,然后jmap设置导出格式

jps
jmap -dump:format=b,file=heap.hprof <pid>

在这里插入图片描述

  • 将,hprof文件导入到MAT工具中进行分析

在这里插入图片描述

很显然,MAT工具已经分析出了占用内存最大的方法所在的类,再进一步分析观察所在类那个对象出现了问题
在这里插入图片描述

  • 元空间内存溢出分析与堆分析思路大体相同

总结:

1、先导出内存映射文件.hprof(两种方法:VM参数、jmap)
2、将导出的文件用MAT工具进行分析,定位出问题所在,修复代码。
3、在实际开发中,内存溢出的问题定位很复杂,在工具的帮助下一步步分析定位到问题代码是开发中非常重要的能力。

导致内存溢出的常见情况:
1、大量使用静态字段
2、未关闭资源导致内存泄漏(数据库连接)
3、不当的equal和hashcode会导致内存泄漏从而导致内存溢出
4、ThreadLocal

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值