测试工程师都能看懂的Jvm知识 下

你好 我是懂java的测试


前言

前两篇文章介绍了一些jvm的理论知识,反响还不错,本篇文章分享一些jvm比较高阶的知识。

还是老规矩,本文将以问答形式,由易到难,循序渐进讲述jvm相关的知识。不拽那些官方晦涩难懂的词语,只想用白话通俗的语言,力争让大家都能看懂jvm。

1、GC日志怎么看

上篇文章最后显示的是GC日志

Java HotSpot(TM) 64-Bit Server VM (25.211-b12) for windows-amd64 JRE (1.
8.0_211-b12), built on Apr  1 2019 20:53:26 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 8133460k(1586644k free), swap 33299284k(15627288k free)
CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=5242880 -XX:NewSize=5242880 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
0.804: [GC (Allocation Failure) [PSYoungGen: 3984K->504K(4608K)] 3984K->2094K(9728K), 0.0034707 secs] [Times: user=0.05 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 4608K, used 3727K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
  eden space 4096K, 78% used [0x00000000ffb00000,0x00000000ffe25c98,0x00000000fff00000)
  from space 512K, 98% used [0x00000000fff00000,0x00000000fff7e010,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 5120K, used 3638K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
  object space 5120K, 71% used [0x00000000ff600000,0x00000000ff98db10,0x00000000ffb00000)
 Metaspace       used 3177K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 347K, capacity 388K, committed 512K, reserved 1048576K

CommandLine flags: -XX:InitialHeapSize=10485760。。。这个是本次运行所使用的默认的Jvm配置,

[GC (Allocation Failure) 意味着新生代,没有多余的空间放置最新的对象,所以会导致youngGc,

PSYoungGen:是使用-XX:+UseParallelOldGC(新生代,老年代都使用并行回收收集器

3984K->504K(4608K) 这个是整个新生代内存状况,新生代有4608K内存容量,回收前已经有3984K了,回收后还剩504K,

3984K->2094K(9728K) 这个是整个堆内存回收状况,堆内存有9728K,gc前使用了3984K,gc后堆内存使用了2094K,

0.0034707 secs,本次gc消耗的时间,因为是youngGc所以时间特别短。

[GC PSYoungGen total 4608K, used 3727K 年轻代总共有4608K,目前使用了3727K,

eden space 4096K, 78% used ,eden区有4096K,78%已经被使用,

from space 512K, 98% used ,from 区有512K,98%已经被使用,

to space 512K, 0% used, eden区有512K,0%已经被使用,

还有ParOldGen(老年代)、Metaspace(元空间) 区域,和上面解读一致,不做赘述。

2、知道哪些jvm相关的命令吗

jstat

jstat命令可以让你看到堆内存区域分配情况,gc的次数和耗时,通过连续输出的形式,可以看到gc的频率和各个区域的容量分布,有利于摸清当前jvm运行的情况。

常见的命令jstat -gc pid 1000 40 其中pid是java进程的id,执行jps命令可获取,整个命令的含义是打印java的gc信息 每隔1000ms 打印40次。

图片

S0C:第一个幸存区的大小

S1C:第二个幸存区的大小

S0U:第一个幸存区的使用大小

S1U:第二个幸存区的使用大小

EC:伊甸园区的大小

EU:伊甸园区的使用大小

OC:老年代大小

OU:老年代使用大小

MC:方法区大小

MU:方法区使用大小

CCSC:压缩类空间大小

CCSU:压缩类空间使用大小

GCT:垃圾回收消耗总时间

YGC: Young GC 代表Minor GC次数;

YGCT: Young GC Time 代表Minor GC耗时;

FGC: Full GC 代表Full GC次数;

FGCT:老年代垃圾回收消耗时间;

GCT: GC Time 代表Minor & Full GC共计耗时;

jmap

‍‍

如果只要简单的看看jvm频率,进行调优,其实jstat命令就已经足够了,

但是如果发现新生代对象新增很快,然后就想看看究竟什么对象创建这么快,可以使用Jmap 命令 。

jmap -heap pid

获取heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况。

jmap -dump:live,format=b,file=myjmapfile.txt 进程id

查看堆内存快照,输出jvm的heap内容到文件, live子选项是可选的,假如指定live选项,那么只输出活的对象到文件

jmap -histo pid

命令会打印出以下信息,可以看到究竟哪个对象占用空间最多

图片

还有其他命令 ,jhat、jps、jinfo等,限于篇幅限制,可自行探索。

3、怎么去定位youngGc问题

本地项目中模拟使用,可复制以下配置到idea中

-XX:NewSize=104857600 -XX:MaxNewSize=104857600 
-XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=3145728 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC 
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log

堆内存设置成200MB,年轻代设置了100MB,Eden区80MB,老年代是100MB,

Idea中项目代码如截图所示

图片

执行jps命令 获取 java进程,java进程号是11744

图片

执行jstat -gc pid 11744 1000 1000,执行结果如下

图片

怎么去分析呢?

单看EU那列,最少也就3M左右空间,之后每秒都会有5M对象新增,eden区域总共才81M左右,直到78M左右,再次增加5M的对象,jvm发现eden放不下了,只能YoungGc,回收大部分对象,回收完,Eden区域就突然下降到1M左右,YGC增加了一次,FGC次数不变,说明只发生了一次YoungGc,YGCT将近0.044秒。

再往下看,15秒左右就会进行一次YoungGc,每次耗时就45毫秒,相对比较频繁,但是耗时45ms勉强可以接受,可不做调优。

4、怎么去定位FullGc问题

还是上面的jvm配置,只是代码稍微修改下

图片

执行jstat

图片

如截图所示,Fgc次最高每秒100多次,虽然每次FGCT时间比较短,但是因为这是模拟创建新增对象,看不出很大影响。

5、JVM调优的原则或步骤是什么

如果是新系统,首先大家应该估算一下自己参与的系统每个核心接口每秒多少次请求,每次请求会创建多少个对象,每个对象大概多大,每秒钟会使用多少内存空间?这样接着就可以估算出来Eden区大概多长时间会占满?然后就可以估算出来多长时间会发生一次Young GC,而且可以估算一下发生You ng GC的时候,会有多少对象存活下来,会有多少对象升入老年代里,老年代对象增长的速率大概是多少,多久之后会触发一次Full GC,通过一连串的估算,就可以合理的分配年轻代和老年代的空间,还有Eden和Survivor的空间。

如果是已经线上运行的项目,可以使用使用jvm的相关命令,查看jvmgc频率和每秒新增的对象大小。

原则就是:尽可能让每次Young GC后存活对象远远小于Survivor区域,避免对象频繁进入老年代触发Full GC。

最理想的状态下,就是系统几乎不发生Full GC,老年代应该就是稳定占用一定的空间,就是那些长期存活的对象在躲过15次Young

GC后升入老年代自然占用的。然后平时主要就是几分钟发生一次Young GC,耗时几毫秒。

总结

至此三篇关于Jvm的分享就结束了,jvm是java的底层技术,在性能调优和面试中占据着重要地位,建议大家看完这三篇文章之后再去搜寻其他学习资料,这样才能在面试中游刃有余,在面试中技术深度这块满分通过。

加我微信,免费面试辅导、学习资料、简历模板获取、加入学习群。

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值