JVM性能分析与定位

一分钟说明

本文章主要是针对现网的cpu和内存性能分析,主要针对Java应用。
涉及知识点:
- top命令
- jstack工具(查看线程)
- jmap工具(查看内存堆栈)
- jstat工具(监控资源和性能)
- jvisualvm可视化工具(配合jmap一起使用)

top命令

  • top -c
    显示进程运行信息列表
    top -c
  • top -Hp <进程号>
    显示这个进程下面的所有线程运行信息列表
    top -Hp <进程号>
    输入大写P,按CPU使用率降序;
    输入大写M,按内存使用率降序;
    TIME列就是各个Java线程耗费的CPU时间。

jstack工具

  • jstack是查看某个Java进程内的线程堆栈信息,JDK自带工具。
  • jstack命令的语法格式:jstack <pid>。可以用jps查看java进程id。

  • 因为堆栈里,线程id是用16进制表示的。所以将获取的线程号(十进制数)转换成十六进制。eg:printf '%x\n' 9912
    转化为16进制

  • jstack <进程号> | grep <16进制线程号>
    jstack使用

  • 线程状态说明

    死锁,Deadlock(重点关注)
    执行中,Runnable
    等待资源,Waiting on condition(重点关注)
    等待获取监视器,Waiting on monitor entry(重点关注)
    暂停,Suspended
    对象等待中,Object.wait() 或 TIMED_WAITING
    阻塞,Blocked(重点关注)
    停止,Parked

    参考链接:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html

jmap工具

  • jmap用来查看java程序堆内存使用状况
  • 命令格式:jmap [ option ] pid

    -dump:[live,]format=b,file= 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
    -finalizerinfo 打印正等候回收的对象的信息.
    -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
    -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
    -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
    -h | -help 打印辅助信息
    -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.

  • *jmap -heap (查看实例)

    Attaching to process ID 31846, please wait…
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 24.71-b01
    using thread-local object allocation.
    Parallel GC with 4 thread(s)//GC 方式
    Heap Configuration: //堆内存初始化配置
    MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
    MaxHeapFreeRatio = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
    MaxHeapSize = 2082471936 (1986.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
    NewSize = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
    MaxNewSize = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
    OldSize = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=:设置JVM堆的‘老生代’的大小
    NewRatio = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
    SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
    PermSize = 21757952 (20.75MB) //对应jvm启动参数-XX:PermSize=:设置JVM堆的‘永生代’的初始大小
    MaxPermSize = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=:设置JVM堆的‘永生代’的最大大小
    G1HeapRegionSize = 0 (0.0MB)
    Heap Usage://堆内存使用情况
    PS Young Generation
    Eden Space://Eden区内存分布
    capacity = 33030144 (31.5MB)//Eden区总容量
    used = 1524040 (1.4534378051757812MB) //Eden区已使用
    free = 31506104 (30.04656219482422MB) //Eden区剩余容量
    4.614088270399305% used //Eden区使用比率
    From Space: //其中一个Survivor区的内存分布
    capacity = 5242880 (5.0MB)
    used = 0 (0.0MB)
    free = 5242880 (5.0MB)
    0.0% used
    To Space: //另一个Survivor区的内存分布
    capacity = 5242880 (5.0MB)
    used = 0 (0.0MB)
    free = 5242880 (5.0MB)
    0.0% used
    PS Old Generation //当前的Old区内存分布
    capacity = 86507520 (82.5MB)
    used = 0 (0.0MB)
    free = 86507520 (82.5MB)
    0.0% used
    PS Perm Generation//当前的 “永生代” 内存分布
    capacity = 22020096 (21.0MB)
    used = 2496528 (2.3808746337890625MB)
    free = 19523568 (18.619125366210938MB)
    11.337498256138392% used
    670 interned Strings occupying 43720 bytes.

  • jmap -histo (查看实例)

    扫描二维码关注公众号,回复: 195061 查看本文章

    jmap

  • jmap -dump:format=b,file=heap.bin

    把内存结构全部dump到二进制文件中
    然后使用jvisualvm可视化工具查看内容结构(eclipse 的MemoryAnalyzer也可以)

jstat

Options,选项,我们一般使用 -gcutil 查看gc情况 vmid,VM的进程号,即当前运行的java进程号 interval,间隔时间,单位为秒或者毫秒 count,打印次数,如果缺省则打印无数次

通常运行命令如下:

jstat -gc 12538 5000
即会每5秒一次显示进程号为12538的java进成的GC情况,
显示内容如下图:
jstat

jstat -gc 21711 250 4
vmid是虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4

  • 说明

    S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
    EC、EU:Eden区容量和使用量
    OC、OU:年老代容量和使用量
    PC、PU:永久代容量和使用量
    YGC、YGT:年轻代GC次数和GC耗时
    FGC、FGCT:Full GC次数和Full GC耗时
    GCT:GC总耗时

  • 显示内容说明如下(部分结果是通过其他其他参数显示的,暂不说明):

    S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
    S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
    S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)

    S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
    EC:年轻代中Eden(伊甸园)的容量 (字节)
    EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
    OC:Old代的容量 (字节)
    OU:Old代目前已使用空间 (字节)
    PC:Perm(持久代)的容量 (字节)
    PU:Perm(持久代)目前已使用空间 (字节)
    YGC:从应用程序启动到采样时年轻代中gc次数
    YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
    FGC:从应用程序启动到采样时old代(全gc)gc次数
    FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
    GCT:从应用程序启动到采样时gc用的总时间(s)
    NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
    NGCMX:年轻代(young)的最大容量 (字节)
    NGC:年轻代(young)中当前的容量 (字节)
    OGCMN:old代中初始化(最小)的大小 (字节)
    OGCMX:old代的最大容量 (字节)
    OGC:old代当前新生成的容量 (字节)
    PGCMN:perm代中初始化(最小)的大小 (字节)
    PGCMX:perm代的最大容量 (字节)
    PGC:perm代当前新生成的容量 (字节)
    S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
    S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
    E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
    O:old代已使用的占当前容量百分比
    P:perm代已使用的占当前容量百分比
    S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
    S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
    ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
    DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
    TT: 持有次数限制
    MTT : 最大持有次数限制

猜你喜欢

转载自blog.csdn.net/luoliang2012/article/details/77882507