http://www.javatang.com/archives/2017/10/20/12131956.html

前面提到了一个使用jstack的shell脚本,通过命令可以很快地定位到指定线程对应的堆栈信息。

使用jstat命令

当服务器CPU100%的时候,通过定位占用资源最大的线程定位到 VM Thread

"VM Thread" prio=10 tid=0x00007fbea80d3800 nid=0x5e9 runnable

这个时候需要使用 jstat -gc <pid> <period> <times> 命令查看gc的信息,显示结果如下:

S0C    S1C    S0U    S1U      EC       EU      OC         OU       PC        PU       YGC     YGCT    FGC   FGCT       GCT
64.0 64.0 0.0 0.0 332992.0 0.0 666304.0 73192.5 83968.0 83967.9 6893 17.576 6882 2705.923 2723.499

结果中每个项目的含义可以参考官方对jstat的文档,简单翻译如下:
- S0C: Young Generation第一个survivor space的内存大小 (kB).
- S1C: Young Generation第二个survivor space的内存大小 (kB).
- S0U: Young Generation第一个Survivor space当前已使用的内存大小 (kB).
- S1U: Young Generation第二个Survivor space当前已经使用的内存大小 (kB).
- EC: Young Generation中eden space的内存大小 (kB).
- EU: Young Generation中Eden space当前已使用的内存大小 (kB).
- OC: Old Generation的内存大小 (kB).
- OU: Old Generation当前已使用的内存大小 (kB).
- PC: Permanent Generation的内存大小 (kB)
- PU: Permanent Generation当前已使用的内存大小 (kB).
- YGC: 从启动到采样时Young Generation GC的次数
- YGCT: 从启动到采样时Young Generation GC所用的时间 (s).
- FGC: 从启动到采样时Old Generation GC的次数.
- FGCT: 从启动到采样时Old Generation GC所用的时间 (s).
- GCT: 从启动到采样时GC所用的总时间 (s).

JDK8的结果稍微有所不同,结果含义可以参考:http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

JVM内存模型

上面中的Young Generation、Permanent Generation和Old Generation等概念有一些混乱,这里简要的进行说明。简单来说,JVM内存由堆(Heap)和非堆(Non-heap)内存组成,前者共运行在JVM之上的程序使用,后者供JVM自己使用。

堆内存的组成如下:

非堆内存由 Permanent Generation 和 Code Cache 两部分组成:

  • Permanent Generation(持久代): 保存虚拟机自己的静态(refective)数据,主要存放加载的Class类级别静态对象如class本身,method,field等等。permanent generation空间不足会引发full GC;
  • Code Cache: 用于编译和保存本地代码(native code)的内存,JVM内部处理或优化。

JVM内存参数设置

堆内存设置

  • 堆内存(总的)由 -Xms 和 -Xmx 分别设置最小和最大堆内存
  • New Generation 由 -Xmn 设置,-XX:SurvivorRatio=m 设置 Eden和 两个Survivor区的大小比值;-XX:NewRatio=n 设置 New Generation 和 Old Generation 的大小比值。
  • 每个线程的堆栈大小由 ·-Xss· 设置,JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

非堆内存设置

非堆内存由 -XX:PermSize=n 和 -XX:MaxPermSize=n 分别设置最小和最大非堆内存大小

日志分析

介绍完上面的概念之后,我们再来看最上面的日志信息,有两个地方有问题:
一是FGC(完全GC)的数量太大了,正常来说FGC应该占整个GC(YGC+FGC)的1%到5%才正常,上面日志上完全GC的次数太多了;二是日志中PU的值太大了,基本上已经达到设置的PC了,因此需要增大MaxPermSize的值。
不过这只是权宜之计,出现这么大的非堆内存,肯定什么地方出现了问题,还需要进一步找到占用内存的原因,这也是后面文章所要说的。

参考资料:
100% CPU diagnosis
JVM调优总结 + jstat 分析
JVM调优总结(这个总结得比较全面)
JVM调优总结系列文章
JVM系列一:JVM内存组成及分配

jstat命令的使用及VM Thread分析的更多相关文章

  1. Java内存泄漏分析系列之三:jstat命令的使用及VM Thread分析

    原文地址:http://www.javatang.com 使用jstat命令 当服务器CPU100%的时候,通过定位占用资源最大的线程定位到 VM Thread: "VM Thread&qu ...

  2. Linux使用jstat命令查看jvm的GC情况(转)

    B. jstack jstack主要用来查看某个Java进程内的线程堆栈信息.语法格式如下: 1 jstack [option] pid 2 jstack [option] executable co ...

  3. Linux使用jstat命令查看jvm的GC情况

    Linux使用jstat命令查看jvm的GC情况 http://www.open-open.com/lib/view/open1390916852007.html http://www.aiuxian ...

  4. 如何在宿主机上执行容器里的jmap,jtack,jstat 命令获取信息(原创)

    一般情况下,我们要获取docker容器里的jvm信息只能进入容器后执行jmap,jstack,jstat 命令去获取,jstack,jstat还好,但是jmap dump的文件要拿出来,得先copy ...

  5. jstat命令详解

    Jstat是JDK自带的一个轻量级小工具.全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令 ...

  6. jstat命令总结

    jvm统计信息监控工具 一. jstat是什么 jstat是JDK自带的一个轻量级小工具.全称"Java Virtual Machine statistics monitoring tool ...

  7. 012 - jstat命令查看jvm的GC情况 | jvm

    jstat命令可以查看堆内存各部分的使用量,以及加载类的数量. 命令的格式如下: jstat -<option> [-t] [-h<lines>] <vmid> [ ...

  8. jvm 性能调优工具之 jstat 命令详解

    Jstat名称:Java Virtual Machine statistics monitoring tool 官方文档:https://docs.oracle.com/javase/1.5.0/do ...

  9. jstat命令查看jvm的GC情况 (以Linux为例)

    jstat命令可以查看堆内存各部分的使用量,以及加载类的数量.命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]  注意!!!:使用的jdk版本是jdk8. ...

随机推荐

  1. [poj] 1236 networks of schools

    原题 这是一道强连通分量板子题. 显然subtask1 是要输出入度为0的点的个数 而subtask2,我们考虑一下最优一定是把一个出度为零的点连到入度为零的点上,这样我们要输出的就是max(出度为零 ...

  2. BZOJ2875 [Noi2012]随机数生成器 【矩阵乘法 + 快速乘】

    题目 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Me thod)来生成一个随机数列,这种方法需要设置四个非负整数参数m,a, ...

  3. 交叉编译HTOP并移植到ARM嵌入式Linux系统

    原创作品,允许转载,转载时请务必以超链接形式标明文章.作者信息和本声明,否则将追究法律责任. 最近一直在完善基于Busybox做的ARM Linux的根文件系统,由于busybox是一个精简的指令集组 ...

  4. Tomcat给我的java.lang.OutOfMemoryError: PermGen

    今天,Tomcat给了我这么一个异常:java.lang.OutOfMemoryError: PermGen space.自己是第一次遇到,抱着好奇的心情google了一下,居然是个很常见的异常!故记 ...

  5. Python之面向对象:闭包和装饰器

    一.闭包 1. 如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包. def outter(): name='python' def inner(): print na ...

  6. linux mint 自动挂载windows的D盘和E盘

    终端敲udisksctl mount -p block_devices/sda后双击tab键补全分区,如下:    如我的E盘是sda6,执行     udisksctl mount -p block ...

  7. Spring3.2+Struts2.3+Mybatis3.2整合使用(注解使用)

    0.包结构:

  8. GPS经纬度的表示方法及换算

    想要认识GPS中的经纬度,就必须先了解GPS,知道经纬度的来源: 1. GPS系统组成 GPS是 Gloabal Positioning System 的简称,意为全球定位系统,主要由地面的控制站.天 ...

  9. github单独现在一个文件夹

    项目地址:https://github.com/src-kun/webshell/但根据需要只想下载其中一个文件夹https://github.com/src-kun/webshell/tree/ma ...

  10. Access数据库 INSERT INTO 失败

    一次操作Access数据库,插入一条数据,总是失败,如下: 通过赋值,一个字段一个字段的排查,最终确定是UserAge字段处有问题. 最初,UserAge字段是 %d 类型的,赋值20,可成功插入数据 ...