面试官:怎么排查堆内存溢出呀?

点赞再看,养成习惯,微信搜索【三太子敖丙】关注这个互联网苟且偷生的工具人。php

本文 GitHub github.com/JavaFamily 已收录,有一线大厂面试完整考点、资料以及个人系列文章。java

上次给小伙伴们说过了死循环cpu飙高的排查过程,今天就带着你们看看堆内存溢出咱们通常怎么排查的。git

  • cpu100%排查文章

在排查以前,我想jvm的基础知识你们应该都是了解了的吧?github

老婆我就是不了解,人家要你说给我听。

行行行,诶真实拿大家没办法,那我就带你们回温一下JVM的内存模型(这玩意跟JAVA内存模型JMM可不同,不要记错了)web

今天我就直说堆,由于溢出是发送在堆中的。面试

JVM堆内存被分为两部分:年轻代(Young Generation)和老年代(Old Generation)。服务器

年轻代

年轻代是全部新对象产生的地方。当年轻代内存空间被用完时,就会触发垃圾回收。这个垃圾回收叫作Minor GC。微信

年轻代被分为3个部分——Enden区和两个Survivor区。eclipse

年轻代空间的要点:

  1. 大多数新建的对象都位于Eden区。
  2. 当Eden区被对象填满时,就会执行Minor GC,并把全部存活下来的对象转移到其中一个survivor区。
  3. Minor GC一样会检查存活下来的对象,并把它们转移到另外一个survivor区。这样在一段时间内,总会有一个空的survivor区。
  4. 通过屡次GC周期后,仍然存活下来的对象会被转移到年老代内存空间,一般这是在年轻代有资格提高到年老代前经过设定年龄阈值来完成的。

年老代

年老代内存里包含了长期存活的对象和通过屡次Minor GC后依然存活下来的对象,一般会在老年代内存被占满时进行垃圾回收。jvm

GC种类

Major GC

老年代的垃圾收集叫作Major GC,Major GC一般是跟full GC是等价的,收集整个GC堆。

分代GC

  1. Young GC:只收集年轻代的GC
  2. Old GC:只收集年老代的GC(只有CMS的concurrent collection是这个模式)
  3. Mixed GC:收集整个young gen以及部分old gen的GC(只有G1有这个模式)

Full GC

Full GC定义是相对明确的,就是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。

你们能够从上图看到年轻代分为了一个Eden区和两个survivor区(S1,S2),survivor区同一时间只会有一个满一个空,交替的。

而后就是GC到必定的阈值到老年代,今天不讲永久代因此忽略Mataspace。

老婆:那怎么分析呢?

今天我就用一个JDK自带的工具jvisualvm来给你们演示一波怎么操做的,由于这玩意谁都有,你去命令行敲一下jvisualvm就出来了(Mac是这样的,不知道Windows是怎么样子的)。

操做界面:

通常什么状况多是出现了溢出呢?

超时,不进行服务,服务挂掉,接口不在服务这样的异常问题。

那模拟也很简单,我写个循环一直往List丢数据,不使用list就能看到现象了

你们能够看到图形化界面仍是很清晰明了的,这个是Visual GC的插件

你们点击菜单栏的插件,而后安装就行了,安装完了记得点击激活。

能够看到不释放,堆空间就一直上去,直到OOM(out of memory)

这个时候咱们就dump下来堆信息看看

会dump出一个这样的hprof快照文件,能够用jvisualvm自己的系统去分析,我这里推荐MAT吧,由于我习惯这个了。

MAT :下载地址

下来好了咱们能够看到mat已经分析了咱们的文件

你看他就是个暖男,都帮咱们分析出来了一个问题,咱们点进去看看

他发现了是ArrayList的问题了,咱们再往下看看

看到了嘛,具体代码的位置都帮咱们定位好了,那排查也就是手到擒来的事情了。

延伸点

上面咱们使用工具jump了,那怎么去服务器上jump呢?

jmap -dump:format=b,file=<dumpfile.hprof> <pid>
复制代码

有朋友可能问了,不是全部的故障当时咱们都在场的,没法及时jump,那也简单

-XX:+HeapDumpOnOutOfMemoryError
复制代码

配置这玩意以后,oom的时候会自动jump的,到时候拿快照分析一波就行了。

MAT的功能还有不少的,百度谷歌太多工具文了,我就不作重复的工做了,好比还能够排查对象的强弱引用,还能够查看引用链等等。

还有个只写这么点的缘由是有点晚了,顶不住了,最近不拍视频也是由于事情多了,有点小忙,但愿你们体量,对了Redis的分布式锁已经在安排的路上了。

我是敖丙,一个在互联网苟且偷生的工具人。

最好的关系是互相成就你们们的 「三连」 就是丙丙创做的最大动力,咱们下期见!

注:若是本篇博客有任何错误和建议,欢迎你们留言,你快说句话啊


文章持续更新,能够微信搜索「 三太子敖丙 」第一时间阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板,本文 GitHub github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

你知道的越多,你不知道的越多

相关文章
相关标签/搜索