从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!

前言

本次邀请的大佬十余年Java行业经验。曾就职于招商银行互联网事业部58同城互联网金融等行业,有丰富的大型项目设计与建设经验。 主要对分布式架构、微服务、数据安全等领域有深入的研究及改造经验。

犹豫大佬不愿意透露姓名,这里我就不给大佬透底了!为了让大佬分享一些他的实战经验,我可是大出血了一回!!!

大家应该都知道什么是 JVM 吧!

JVMJava Virtual Machine(Java虚拟机) 的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够 “一次编译,到处运行的” 原因。

详细的介绍可以去看我之前的一篇文章!JVM知识点详解!

正文

项目介绍

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第1张图片

代码介绍

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第2张图片
在 Linux 服务跑起来

java -cp ref-jvm3.jar -XX:+PrintGC -Xms200M -Xmx200M ex13.FullGCProblem

CPU 占用过高排查实战

  1. 先通过 top 命令找到消耗 cpu 很高的进程 id 假设是 2732

top 命令是我们在 Linux 下最常用的命令之一,它可以实时显示正在执行进程的 CPU 使用率、内存使用率以及系统负载等信息。其中上半部分显示的是系统的统计信息,下半部分显示的是进程的使用率统计信息。
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第3张图片

  1. 执行 top -p 2732 单独监控该进程
  2. 在第 2 步的监控界面输入 H,获取当前进程下的所有线程信息

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第4张图片

  1. 找到消耗 cpu 特别高的线程编号,假设是 2734(要等待一阵)
  2. 执行 jstack 2732 对当前的进程做 dump,输出所有的线程信息

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第5张图片

  1. 将第 4 步得到的线程编号 2734 转成 16 进制是 AAE

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第6张图片
也可以通过计算器来换算。

  1. 根据第 6 步得到的 0x7b 在第 5 步的线程信息里面去找对应线程内容
  2. 解读线程信息,定位具体代码位置

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第7张图片

发现找是 VM 的线程占用过高,我们发现我开启的参数中,有垃圾回收的日志显示,所以我们要换一个思路,可能是我们的业务线程没问题,而是垃圾回收的导致的。
代码中有打印 GC 参数,生产上可以使用这个 jstat –gc 来统计,达到类似的效果

是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载内存垃圾收集JIT 编译等运行数据,在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。

假设需要每 250 毫秒查询一次进程 13616 垃圾收集状况,一共查询 10 次,那命令应当是:jstat-gc 13616 250010

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第8张图片

使用这个大量的 FullGC
还抛出了 OUT Of Memory

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

怎么办?OOM 了。

我们可以看到,这个里面 CPU 占用过高是什么导致的?

是业务线程吗?不是的,这个是 GC 线程占用过高导致的JVM 在疯狂的进行垃圾回收,再回顾下之前的知识,JVM 中默认的垃圾回收器是多线程的(回顾下之前的知识),所以多线程在疯狂回收,导致 CPU 占用过高

内存占用过高内存占用过高思路

用于生成堆转储快照(一般称为 heapdumpdump 文件)。jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalize 执行队列Java 堆永久代的详细信息,如空间使用率当前用的是哪种收集器等。和 jinfo 命令一 样,jmap 有不少功能在 Windows 平台下都是受限的,除了生成 dump 文件的 -dump 选项和用于查看每个类的实例、 空间占用统计的 -histo 选项在所有操作系统都提供之外
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第9张图片
JVM 中的对象全部打印出来, 但是这样太多了,那么我们选择前 20 的对象展示出来, jmap –histo 1196 | head -20
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第10张图片
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第11张图片
定位问题的关键,就是这条命令。

很多个 88 万个对象。
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第12张图片

问题总结(找到问题)

一般来说,前面这几行,就可以看出,到底是哪些对象占用了内存。

这些对象回收不掉吗?是的,这些对象回收不掉,这些对象回收不掉,导致了FullGC,里面还有 OutOfMemory

从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第13张图片
从业三年连JVM如何调优都不知道怎么涨薪?快来看看大佬是怎么进行JVM调优实战的!_第14张图片
任务数多于线程数,那么任务会进入阻塞队列,就是一个队列,你进去,排队,有机会了,你就上来跑。

但是同学们,因为代码中任务数一直多于线程数,所以每 0.1S,就会有 50 个任务进入阻塞对象,50 个任务底下有对象,至少对象送进去了,但是没执行。

所以导致对象一直都在,同时还回收不了。

为什么回收不了。Executor 是一个 GCroots

所以堆中,就会有对象 80 万个,阻塞队列中 80 万个任务,futureTask。并且这些对象还回收不了。

总结

在 JVM 出现性能问题的时候。(表现上是 CPU100%,内存一直占用)

  1. 如果 CPU 的 100%,要从两个角度出发,一个有可能是业务线程疯狂运行,比如说想很多死循环。还有一种可能性,就是 GC 线程在疯狂的回收,因为 JVM 中垃圾回收器主流也是多线程的,所以很容易导致 CPU 的 100%
  2. 在遇到内存溢出的问题的时候,一般情况下我们要查看系统中哪些对象占用得比较多,我的是一个很简单的代码,在实际的业务代码中,找到对应的对象,分析对应的类,找到为什么这些对象不能回收的原因,就是我们前面讲过的可达性分析算法JVM 的内存区域,还有垃圾回收器的基础,当然,如果遇到更加复杂的情况,你 要掌握的理论基础远远不止这些(JVM 很多理论都是排查问题的关键)

看在我大出血给大家带来好东西的份上,最后来一个一键三连不过分吧!!!

你可能感兴趣的:(java,jvm,linux,分布式,java虚拟机)