高并发服务优化篇:JVM--工程师进阶的必经之路原创
这篇是最近重发的JVM调优相关的文章汇总,考虑到应该隶属于高并发的服务端优化系列,现在系列文章涉及到了这一块,为了完整性就汇总在一起来填补这块的内容。看过的可以忽略,建议收藏,万一后面有遇到可以做个参考。
前言
JVM调优,是一个JAVA工程师在进阶道路上的必经之路。每一次真实的生产环境下的调优经历和总结,都对整个JVM体系知识的融会贯通有很大的作用。
Java为了实现跨平台、高度抽象等特性,增加了JVM来实现Java代码到机器码的转换。这给运行速度增加了不少损耗,但是好处也很多,诸如内存管理、垃圾回收等容器级通用功能,让研发人员可以更加聚焦业务。
其中,GC技术用来进行内存自动管理,避免手动管理带来的指针悬挂问题,让开发人员可以不再过多的关注内存,很大程度上提升了开发效率。
然而,有利也有弊,这种类黑盒的管理功能,让我们开发同学对内存的把控程度有所下降。发生问题时的排查成本也随之增加。
GC日志是很多jvm问题排查和定位的第一道工具。比如
-
如果我们发现old区上升较快,s区却没有变化,是不是可以猜测是s区大小设置的和当前系统的对象大小不合适,导致没有进过s区的年代晋升直接到了老年代; -
又或者我们发现频繁fgc, gc日志中fgc之后 堆大小变化不大,是不是可以从内存泄露这个方向去分析dump文件。 -
又或者我们在进行了一系列业务逻辑优化后,系统的响应任然不尽人意,碰巧公司暂时还没有成熟的监控平台,那从GC日志的耗时分析出发,就成了分析问题的必然之路了。
生产环境GC日志要遵循够用就好的原则,因为GC日志的打印时间也会被算在STW中。那么,需要打印哪些,怎么设置对应的参数,就有一些讲究了。
主要列举了基础的必备参数以及一些比较关键的,或者说比较容易忽略,但是有可能引起GC异常的信息监控:如GC日志文件滚动、禁写Statistics数据、安全点相关参数等。
Young GC的问题其实是比较难排查的,这里汇总了一些可行的排查思路和方向,绝大部分应该都逃不出这个范围。
-
等待线程到达安全点导致young gc时间增加。比如,大循环、线程间竞争等等。从GC日志中安全点中,和等待的线程数可以看出端倪。 -
存活对象扫描和标记导致时间异常。本地缓存过多、 system class loader 加载对象过多、JNI & Monitor & finalizable等都可能是罪魁祸首。 -
其他的还有eden区大小设置不当导致的对象copy增多,以及GC日志打印,都是排查young gc耗时异常时需要重点关注的地方。
JVM调优大图一览
方法总比困难多,通过一次次的采坑,总结出了一些规范和行之有效的应对方向。希望对大家日常开发和问题排查有所帮助。
对于文章,或者对于JVM调优有什么问题,欢迎大家留言或者加好友探讨交流~
推荐阅读: