前言:最近面试发现很多面试官都挺喜欢问如何监控到线上的死锁,内存溢出及泄露,以及如何发现并解决?作为一名长期埋头工作的码农,问到这块知识点,答得不让面试官满意是很正常的,毕竟工作中的大部分情况都不是在处理死锁,内存溢出及泄露,长时间不碰的知识点实在是太容易忘了,这里再总结一番.在面试造航母,工作拧螺母的大背景下,程序员的竞争已经非常激烈了,企业需要用最少的钱,招能写的了代码,且出问题还具备解决能力的码农,吾等打工人只能硬着头皮往前冲!
关于死锁,内存溢出,内存泄露的监控主要有两类方式,基础命令监控和工具监控,这两种方式各有优劣,所以针对这两类监控方式我分别写一篇来总结,本篇主要介绍通过基础命令监控,下篇重点介绍通过工具监控和解决,推荐是两种方式都掌握,时间有限非要二选一的话可以跳过本篇直接翻到文末看下篇.
目录
1.基础命令监控的优劣
2.基础命令介绍
3.如何发现并解决死锁
4.如何发现并解决内存溢出
5.如何发现并解决内存泄露
6.总结
优:可以不受机器,环境,条件的限制,随时随地,敲个命令就能发现问题,简单快捷又高效,甚至还能装一把A和C之间的字母...
劣:对码农要求高,如果不长期实践,命令及参数含义容易忘记,监控不够直观,分析起来也比较费劲,没两把刷子挺难的...
关于Jvm需要了解的基础命令主要有jps,jstack,jmap,jhat,jstat
jps :主要记录Jvm的进程状态,常用参数为-l,列出所有java应用的进程:
jstack:主要用于查看java进程内的线程堆栈信息,常用参数为-l [pid],列出指定进程id的堆栈信息:
jmap:主要用于查看堆内存使用情况,一般会结合jhat一起使用,常用参数为-heap [pid],用于查看进程堆内各区内存使用情况:
jhat:全称 java heap analysis tool(java 堆分析工具),主要用于分析jmap dump出来的文件,提供可视化的界面进行分析,所以通常会配合jmap命令一起使用,我们先用jmap -dump:format=b,file=xxx.mat [pid] 去导出dump文件到指定目录下
然后通过命令:jhat -port xxxx filePath 就可以启动一个指定端口的服务,然后在浏览器中直接访问了:
一个简易版的分析工具就这样简单搭好了.
jstat:可以用来查看类加载情况(如class数量,耗时等),不过通常会被用来查看jvm GC情况,语法:jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
如果第一次没看懂这图啥意思也不要紧,可以先看下jvm的堆和非堆内存划分:
堆区=Young区+Old区
Young区=Eden区+Survivor区(其中S区被划分为两块等大的s0,s1区,采用标记复制算法)
非堆=Permanent (JDK8后为MetaSpace)
这些知识点不再啰嗦了,没有自己恶补...
上面jstat的图中,字母C是Capacity(容量)的缩写,U是Useage(使用情况)的缩写,F是Full的缩写,T是Time的缩写了解了这些之后,再来看就很好懂了:
S0C:S0区的容量,S0U:S0区的内存使用情况...
CCSC:当前压缩类空间容量,CCSU:当前压缩类空间使用情况(都是针对MetaSpace使用情况)...
FGC:FullGC次数,FGCT:FullGC耗时,GCT:GC总耗时
前面了解了Jvm的常用命令,针对死锁盲猜也是要用到jstack来查看线程堆栈信息:
jstack -l [pid]
即可发现死锁.
内存溢出比较好发现,通过查看线上日志,哪里OOM了,就能定位,如果要提前发现可能将会发生内存溢出的地方,可以通过jmap -heap 查看各区域内存使用情况,太小或使用量较高的地方重点关注
通过命令发现内存泄漏是非常困难的,除非你对整个系统的代码非常了解,配合命令和日志你可以大致定位到可能出现内存泄漏的地方,然后缩小范围,在对应范围内的代码进行排查.
本篇其实通篇没提如何解决死锁,内存溢出及泄漏,也没有用代码去演示如何模拟出这些问题,我会在下篇重点去讲,本篇的重点其实是命令本身,需要了解每个命令是干什么的,然后能够熟练掌握常用命令及参数以及能看懂返回的内容,在实际应用中,绝大多数场景都是用工具去监控和解决问题的,效率比较高,门槛也低,当然这些基础命令也会有派的上用场的时候,所以推荐掌握.
传送门: 【jvm】面试官求你别再问了-死锁,内存溢出及泄漏如何监控及解决(下)