性能测试:jstat -gcuti命令分析

前言

jstat中如何查看当前内存消耗是否存在问题?jvm是否需要调优,我们该如何去分析?


一、jstat命令用法: jstat -gcutil PID 1000

1:找到PID:ps -ef |grep 进程名
2:jstat -gcutil PID 1000 表示每隔1s执行一次
3:输出结果:
性能测试:jstat -gcuti命令分析_第1张图片
S0 — Heap上的 Survivor space 0 区已使用空间的百分比
S1 — Heap上的 Survivor space 1 区已使用空间的百分比
E — Heap上的 Eden space 区已使用空间的百分比
O — Heap上的 Old space 区已使用空间的百分比
M — 元数据区使用比例

YGC — 从应用程序启动到采样时发生 Young GC 的次数
FGC — 从应用程序启动到采样时发生 Full GC 的次数
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)

二、jstat分析JVM套路

1:jvm体系结构图

JVM 内存结构分为了 年轻代(Young) 、年老代(Old)、元空间(Perm)
年轻代:复制算法

  1. 所有新生成的对象首先都是放在年轻代的,年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象

性能测试:jstat -gcuti命令分析_第2张图片

2:JVM 中 对象从创建到回收过程理解(结合上图理解)
a: YoungGC过程理解

新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个Eden区,两个 Survivor区。新new出来的对象会存储在 Eden(伊甸园)中,当这区域满了之后JVM会进行一次垃圾回收,在回收时把有用的对象存储在S1区,没用的就销毁此对象的内存空间,这过程即第一次YoungGC,如果S1区空间也满了后,同理会将有用的对象会放到S2区中,并释放S1空间,以上反复的回收即为YoungGC。
性能测试:jstat -gcuti命令分析_第3张图片

b: FullGC过程理解

年轻代空间满了之后,会将满足一定活跃度的对象放到Old区中(对象活跃度:每个对象满足JVM默认count=15之后就判断是活跃对象,每次YoungGC后会将存活对象生命中+1,直到=15就转到Old区,这个次数可以通过:-XX:MaxTenuringThreshold来配置), 由于Full GC需要对整个堆进行回收,导致应用访问变慢,因此应该尽可能减少Full GC的次数。
性能测试:jstat -gcuti命令分析_第4张图片

三、JVM内存回收如何判定回收不彻底?可能导致内存泄漏或溢出

如果 S0 S1 伊甸园区 这三个空间都有值的时候说明可能存在问题。因为正常情况下是每次GC后,S0区、S1区中的空间总有一个是会被完全清空(根据GC垃圾回收算法),因此S0 S1一直存在被占用时则回收不彻底,导致内存泄漏现象,随之时间拉长,甚至出现内存溢出(OOM)现象。
性能测试:jstat -gcuti命令分析_第5张图片

总结

  1. 年轻代:复制算法
    所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象

  2. 年老代:标记-清除或标记-整理算法
    在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象

  3. 在压力测试过程中发现Eden区内存增加过快,根据压测VU和业务判断是否合理,从而判断YoungGC频率是否正常。

  4. FullGC频率一般在半小时一次较为正常,具体根据真实业务判断,那么在压力测试过程中,监控到FullGC次数过多,则需根据压测业务结合代码分析定位。

你可能感兴趣的:(性能测试,linux,jvm,内存泄漏)