list数据过大导致内存溢出_什么,系统内存溢出了?记一次JVM调优实战

这里我们不讲JVM的内存划分,垃圾判定算法,垃圾回收算法,垃圾收集器等知识。主要讲的是实际调优的操作,对JVM调优感兴趣的可以看下去。至于垃圾回收算法,可以看看我这篇文章:

https://mp.weixin.qq.com/s?__biz=Mzg4NDMyNTIwMw==&mid=2247487158&idx=1&sn=4a36bf8eec50b584a1ac08069e32afeb&chksm=cfb8a08af8cf299c089ff889c6a42ba18bbaccd054135d0c78eeb69bfda6f28796c3ba9d6625&token=150423897&lang=zh_CN&scene=21#wechat_redirect

公司系统出现内存溢出的故障,下面是内存溢出排除过程,我采用伪代码模拟了生产环境。

public class MemoryLeakService {    public List distinct() throws InterruptedException {        List list = new ArrayList<>();        CountDownLatch downLatch = new CountDownLatch(1);        new Thread(() -> {            try {                for (int j = 0; j 

这里主要是模拟一个缓存加载的过程,将用户数据加载进List集合中。为了体现效果,我们将堆内存调小,并将内存溢出的堆栈信息打印出来,具体指令如下:

-Xmx8m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/temp/20200824.hprof

当运行系统时,出现如下报错

004a3b2101501796dc1bee5d596c3547.png

我们发现Thread-1的堆空间内存溢出了,并且生成如下文件20200824.hprof。

40ed17c749e55692a3732d490cdf3b94.png

打开内存分析工具 Eclipse Memory Analyzer

1ddcf141b7fa92ae2964b7eafea9854a.png

加载20200824.hprof文件,找到有问题的堆栈信息

c70e41330905704ffafe84b78f9f81d7.png

控制台打印显示Thread-1由内存溢出,我们进Thread-1看

a36e6382a422844493f1bd18712a2be9.png

点击箭头处按钮

3053b0027be9d96e92140f5776c86827.png

选择线程明细

51254b940ad3f4bf332a5a9b7fcdb588.png
a861e36fd353eef756dab4f447989533.png

我们发现MemoryLeakService第24行代码有问题,看看第24行代码

a8c0c1c7f3d46a490fa1774e5a9762db.png

是这个对象导致的。

仔细看代码,发现User对象存入了List集合中

if (!list.contains(user)) { list.add(user);}

看看contains()源码

d1838f96435b316bbc254b226c9ee619.png

发现这里是比较的地址值,那!list.contains(user)永远为true。这里就相当于List存了个User。

我们需要重写User的equals方法

@Overridepublic boolean equals(Object o) {    if (this == o) {     return true;    }    if (o == null || getClass() != o.getClass()) {     return false;    }    User user = (User) o;    return Objects.equals(id, user.id);}@Overridepublic int hashCode() { return Objects.hash(id, name, age);}

再次运行,没有出现内存溢出了。

4c3cd654e8d2e2cffae3dc97e51112ed.png

好了,上面就是一次简单的内存溢出查找的过程了,关于工具Eclipse Memory Analyzer的使用,自己可以去网上下载下来,练习使用下。说不定哪天你们的系统真的出现内存溢出,自己就有用武之地了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值