美文网首页js css htmlJava类
JVM调优-JVM调优实践一

JVM调优-JVM调优实践一

作者: 安安_660c | 来源:发表于2023-01-27 19:52 被阅读0次

    1.写在前面

    前面已经分享了很多关于jvm的知识,具体的详情都可以查看上几篇的文章。

    从jvm的调优原理,垃圾查找算法,垃圾回收算法,再到jvm调优工具,调优参数等。

    需要掌握的jvm知识,已经是循序渐进,一步一步的深入学习。

    那在掌握这些内容的时候,是不是有种想去实践的冲动呢?

    好了,今天我们就来进行一次jvm调优实践之旅吧!!!

    主要从以下几个方面进行展开描述:

    • JVM实践调优主要步骤
    • 分析GC日志
    • 堆内存与元空间优化
    • 线程堆栈优化
    • 堆内存内部优化:新生代和老年代比例
    • 垃圾回收器优化

    2.JVM调优实践

    2.1 JVM实践调优主要步骤

    默认的策略是最普用,但不是最佳的。

    • 第一步:监控分析GC日志

    • 第二步:判断JVM问题:

      • 如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化
      • 如果GC时间超过1-3秒,或者频繁GC,则必须优化。
    • 第三步:确定调优目标

    • 第四步:调整参数

      • 调优一般是从满足程序的内存使用需求开始,之后是时间延迟要求,最后才是吞吐量要求,要基于这个步骤来不断优化,每一个步骤都是进行下一步的基础,不可逆行之。
    • 第五步:对比调优前后差距

    • 第六步:重复: 1 、 2 、 3 、 4 、 5 步骤

      • 找到最佳JVM参数设置
    • 第七步:应用JVM到应用服务器:

      • 找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。

    以上,就是我们进行jvm调优得一些步骤了。

    那我们就从第一步开始喽!!!_

    2.2 分析GC日志

    2.2.1 初始参数设置

    机器环境:

    指标 参数
    机器 CPU 12核,内存16GB
    集群规模 单机
    seqb_web版本 1.0
    数据库 4核 16G

    Jvm调优典型参数设置;

    1. -Xms堆内存的最小值:
      • 默认情况下,当堆中可用内存小于40%时,堆内存会开始增加,一直增加到-Xmx的大小。
    2. -Xmx堆内存的最大值: 默认值是总内存/64(且小于1G)
      • 默认情况下,当堆中可用内存大于70%时,堆内存会开始减少,一直减小到-Xms的大小;
    3. -Xmn新生代内存的最大值:
      • 1.包括Eden区和两个Survivor区的总和
      • 2.配置写法如:-Xmn1024k,-Xmn1024m,-Xmn1g
    4. -Xss每个线程的栈内存:
      • 默认1M,一般来说是不需要改。线程栈越小意味着可以创建的线程数越多

    整个堆的大小 = 年轻代大小 + 年老代大小,堆的大小不包含元空间大小,如果增大了年轻代,年老代相应就会减小,官方默认的配置为年老代大小/年轻代大小=2/1左右;

    建议在开发测试环境可以用Xms和Xmx分别设置最小值最大值,但是在线上生产环境,Xms和Xmx设置的值必须一样,防止抖动;

    这里比较重要喔,一般我们都是将Xms和Xmx的值设置为一样的!!!

    JVM调优设置合大小堆内存空间,既不能太大,也不能太小。那么应该设置为多少呢?

    默认的配置是否存在性能瓶颈。如果想要确定JVM性能问题瓶颈,需要进一步分析GC日志

    1. -XX:+PrintGCDetails 开启GC日志创建更详细的GC日志 ,默认情况下,GC日志是关闭的
    2. -XX:+PrintGCTimeStamps,-XX:+PrintGCDateStamps 开启GC时间提示
      • 开启时间便于我们更精确地判断几次GC操作之间的时两个参数的区别
      • 时间戳是相对于 0 (依据JVM启动的时间)的值,而日期戳(date stamp)是实际的日期字符串
      • 由于日期戳需要进行格式化,所以它的效率可能会受轻微的影响,不过这种操作并不频繁,它造成的影响也很难被我们感知。
    3. -XX:+PrintHeapAtGC 打印堆的GC日志
    4. -Xloggc:./logs/gc.log 指定GC日志路径

    这里,我们是在window下面进行测试,idea配置如下:

    image.png

    -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:E:/logs/gc-default.log

    这样就会在e盘下logs文件夹下面,生成gc-default.log日志

    image.png

    2.2.2 GC日志解读

    Young GC 日志含义

    2022-08-05T13:45:23.336+0800: 4.866: [GC (Metadata GC Threshold) [PSYoungGen: 136353K->20975K(405504K)] 160049K->48437K(720384K), 0.0092260 secs] [Times: user=0.00 sys=0.02, real=0.02 secs] 
    
    

    这里的内容,我们一个一个解析:

    
    2022-08-05T13:45:23.336+0800: 本次GC发生时间
    4.866: 举例启动应用的时间
    [GC【表示GC的类型,youngGC】 (Metadata GC Threshold) 元空间超阈值
    [PSYoungGen: 136353K->20975K(405504K年轻代总空间)] 160049K->48437K(720384K)整堆), 0.0092260 secs本次垃圾回收耗时]
    [Times: user=0.00本次GC消耗CPU的时间 sys=0.02系统暂停时间, real=0.02 secs实际应用暂停时间]
    
    
    

    这里的解析,应该很详细了吧,还有谁看不懂的呢?

    FullGC 日志含义

    2022-08-05T20:24:47.815+0800: 6.955: [Full GC (Metadata GC Threshold) [PSYoungGen: 701K->0K(72704K)] [ParOldGen: 38678K->35960K(175104K)] 39380K->35960K(247808K), [Metaspace: 56706K->56706K(1099776K)], 0.1921975 secs] [Times: user=1.03 sys=0.00, real=0.19 secs] 
    
    

    这里的内容,我们也是一个一个解析:

    2022-08-05T20:24:47.815+0800:
    6.955: 刚启动服务就Full GC【整堆回收!!】
    
    [Full GC (Metadata GC Threshold) Metaspace空间超限!
    [PSYoungGen: 701K->0K(72704K)] 年轻代没有回收空间
    [ParOldGen: 38678K->35960K(175104K)] 39380K->35960K(247808K), 老年代也没有到阈值,整堆更没有到阈值
    [Metaspace: 56706K->56706K(1099776K)], 0.1921975 secs]
    [Times: user=1.03本次GC消耗CPU的时间 sys=0.00系统暂停时间, real=0.19 secs实际应用暂停时间] 
    
    
    

    看到这里,有些哥们就会说,这么看,也太恶心了吧,密密麻麻的日志,看着头疼!!!

    那么接下来我们来学一个GC日志可视化工具

    2.2.3 GC日志可视化分析

    分析GC日志,就必须让GC日志输出到一个文件中,然后使用GC日志分析工具(gceasy.io/) 进行分析

    image.png

    这里分析完之后,可以下载分析报告

    image.png
    1) JVM内存占用情况:
    image.png
    Generation【区域】 Allocated【最大值】 Peak【占用峰值】
    Young Generation【年轻代】 74.5 mb 74.47 mb
    Old Generation【老年轻代】 171 mb 95.62 mb
    Meta Space【元空间】 1.05 gb 55.38 mb
    Young + Old + Meta space【整体】 1.3 gb 212.64 mb
    2) 关键性能指标:
    image.png

    1 、吞吐量: 百分比越高表明GC开销越低。这个指标反映了JVM的吞吐量。

    • Throughput97.043%

    2 、GC 延迟Latency

    • Avg Pause GC Time: 7.80 ms 平均GC暂停时间
    • Max Pause GC Time: 190 ms 最大GC暂停时间
    3) GC 可视化交互聚合结果
    image.png

    由上图可以看到,发生了3次full gc

    存在问题:一开始就发生了 3 次full gc , 很明显不太正常;

    4) GC 统计
    image.png

    GC Statistics:GC统计

    由上图可以得到,发生gc的总次数,young gc,full gc的统计,gc 暂停时间统计。

    5) GC原因:
    image.png
    原因 次数 平均时间 最大时间 总耗时
    Metadata GC Threshold 6 43.3 ms 190 ms 260 ms
    Allocation Failure 53 3.77 ms 10.0 ms 200 ms

    这里对这些原因解析一下:

    1. Metadata GC Threshold: 元空间超阈值
    2. Allocation Failure :年轻代空间不足

    这里补充一个原因,本案例还没出现的

    1. Ergonomics:译文是“人体工程学”,GC中的Ergonomics含义是负责自动调解gc暂停时间和吞吐量之间平衡从而产生的GC。目的是使得虚拟机性能更好的一种做法。

    由此可见,通过可视化的工具,可以快速的帮我们分析GC的日志。我们得善于利用工具。

    因为gc的日志文件,内容太多,都是密密麻麻的数字,文本。看得实在是头疼。

    有了gc easy可视化工具,而且还是在线的,十分的方便。GC日志分析是免费的

    由于jvm调优实践的分析,篇幅比较长,所以今天就先到这里,剩下的留着下次分享了。


    好了,以上就是JVM调优实践一的分享了。

    个人理解,可能也不够全面,班门弄斧了。

    如果觉得有收获的,帮忙点赞、评论、收藏一下呗!!!

    相关文章

      网友评论

        本文标题:JVM调优-JVM调优实践一

        本文链接:https://www.haomeiwen.com/subject/iziehdtx.html