龙空技术网

阿里二面:JVM之检测死锁与内存溢出

马士兵老师 1157

前言:

而今我们对“代码内存溢出”大体比较关怀,朋友们都想要学习一些“代码内存溢出”的相关资讯。那么小编也在网络上收集了一些关于“代码内存溢出””的相关文章,希望朋友们能喜欢,同学们快快来了解一下吧!

1.说明

我们在进行JVM调优的时候经常会遇到OOM跟死锁等待,所以如果发现了这两类情况,那就必须把他们检测出来,检测哪一部分出现了问题,使用一些工具将问题给定位出来并且解决,合理的进行调优。

当然JVM调优不是一蹴而就的,JVM调到最优需要进行多次调优,而且也不存在最优解,因为你可能会发现,这一次调优已经很好了,但是修改一下参数可能又比上一次更优。

经常遇到的错误OOM(out of memory)其实就是内存溢出(堆内存溢出),堆内存溢出之后通过定位发现问题,分析问题,解决问题解决方式多种,例如加大内存、bug修复等

死锁这也是一个影响项目响应时间的一大因素,如果部署的程序突然没有反应了,那么就可以查询一下是否程序产生了死锁。

2.内存溢出

堆内存溢出OOM,将堆内存设置小一些,内存溢出的时候将文件Dump下来,记录内存溢出时刻堆内存的情况便于分析

2.1示例操作:

尝试创建 1000 万个字符串并将其添加到 ArrayList,每个字符串都是 1000 个随机生成的 UUID 的串联。由于程序使用了大量内存,会导致 OutOfMemoryError。每次运行内部循环时,都会创建一个新的 String 对象来保存 1000 个 UUID 的串联。由于 Java String 是不可变的,因此每次连接都会创建一个新的 String 对象,这会导致使用大量内存。ArrayList 还持有对所有这些 String 对象的引用,进一步增加了内存使用量。

先模拟出OOM然后再对其进行分析讲解。

代码:

代码保存的路径不要使用中文路径。会找不到

配置VM options:

输出dump文件

配置:-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError,当内存溢出输出hprof文件(dump文件)

运行代码:

发生内存溢出,获取到Dump文件

2.2实际定位分析:

使用Mat软件检测,Mat在我前面JVM说明中有说明。Mat下载存放的路径也不能存在中文

将内存溢出所获取到的Dump文件放入MAT,MAT自动分析。

可以看到,有86.31%的内存由Object[]数组占有,所以比较可疑。

分析:已经有超过80%的内存都被它占有,这是非常有可能出现内存溢出的。 查看详情:点击Detail

可以看到集合中存储了大量的uuid字符串。说明内存溢出部分就在这个字符串存储的部分。

这样就能简单定位到内存溢出的部分了。

3.死锁检测

死锁问题一般都是线程的问题。

3.1示例操作:

将java文件传入服务器,并且运行这个java类。

Java 代码创建了两个并发运行的线程,Thread1 和 Thread2。两个线程都尝试以不同的顺序获取两个不同对象 obj1 和 obj2 的锁。

Thread1 获得了 obj1 的锁,然后休眠了 2 秒。在此期间,Thread2 获得了 obj2 上的锁。2 秒过后,Thread1 尝试获取 obj2 上的锁,同时仍持有 obj1 上的锁。如果 Thread2 还持有 obj2 上的锁并等待 obj1 上的锁,这会造成潜在的死锁情况。如何进行检测说明

3.2实际定位分析:

在死锁的定位中我们使用的是Arthas来检测,Arthas在我前面JVM说明中有说明。启动Arthas。使用thread -b来查看正在运行的线程。当然上边的java类也是需要启动的,你需要再次启动一个服务器操作界面进行Arthas的操作

可以准确知道: 死锁在代码的中的第几行,输出里可以看出死锁在23行

原文链接:

标签: #代码内存溢出