我的JVM(八):常用命令和实战调优场景

一、概述

    实际项目中,时常会有已经上线的问题出现问题,那么我们如何能够让项目能够健壮的运行呢?那么就需要我们进行诊断和分析,今天本文我们就来学习一下JVM常用命令和实战调优场景。

二、解析

    1. 选择垃圾收集器的原则(吞吐量/反应时间)

    我们先来介绍两个概念:

        (1) 吞吐量 = 用户代码执行时间/(用户代码执行时间+垃圾收集执行时间)

        (2) 反应时间快 = 用户线程停顿的时间短

    我们可以针对不同的业务场景来选择锁使用的垃圾回收器的组合,如下:

        (1) 单CPU或小内存,单机程序:-XX:+UseSerialGC

        (2) 多CPU,需要最大吞吐量,如后台计算型应用:-XX:UseParallelGC或者-XX:UseParallelOldGC

        (3) 多CPU,追求低停顿时间,需快速响应如互联网应用:-XX:+UseConcMarkSweepGC

    2. 生产环境常用组合

    具体组合的详细信息,如下图:

在这里插入图片描述

    一般常用的就是PSPO,PN+CMS,G1这3种。

    3. 常用参数设定

    垃圾回收器的常用参数如下:

    

    4. 何时触发YGC与FGC

    触发YGC:

        (1)  新生代的eden区空间不足

    触发FGC:

        (1)  old空间不足

        (2) 显示调用System.gc() ,包括RMI等的定时触发

        (3) YGC时的悲观策略,它触发的机制是在首先会计算之前晋升的平均大小,也就是从新生代,通过ygc变成新生代的平均大小,然后如果老年代剩余的空间小于晋升大小,那么就会触发一次FullGC。sdk考虑的策略是, 从平均和长远的情况来看,下次晋升空间不够的可能性非常大, 与其等到那时候在fullGC 不如悲观的认为下次肯定会触发FullGC, 直接先执行一次FullGC。而且从实际使用过程中来看, 也达到了比较稳定的效果。

        (4) dump live的内存信息时(jmap –dump:live)

    5. CMS参数设定

    CMS参数详情如下图:

    6. G1参数设定

    如下图:

    7. GC日志分析

    不同的垃圾回收器的GC日志格式是不一样的,我们先来分析一下PS的:

    (1) 代码源码如下:

    

    (2) 设置堆大小并且打印日志信息

    

    (3) PS垃圾回收器GC日志详解如下:

    

    Times:user用户态花费的时间;sys内核态花费的时间;real总共花费的时间

    (4) 内存溢出后,会将整个堆的信息打印出来,如下图:

    

    由上图可知,total = eden + from或者to,因为每次使用时,要么使用from,要么使用to。也就是两个survivor区因为copying算法,每次使用的时候只能使用到其中的一个。

    8. JVM调优-预调优

    (1) 熟悉业务场景,选择合适的垃圾回收器组合,响应时间和吞吐量做为选择依据。

    (2) 预估机器配置,计算内存需求,需要多少G运行内存,CPU核数在预算范围内尽可能的多。

    (3) 设定好年代分区比例和新生代转到老年代的年龄等。

    (4) 设置GC日志打印文件,以便以后做问题追踪定位。设定日志参数,包含日志文件名、文件个数、每个文件大小等,具体参数如下:

    

    (5)案例分析:

    a. 垂直电商每日百万订单,订单系统需要什么样的服务器配置?

        可以先做统计,看这一天哪个时间段订单并发量最高,可以根据最高并发数量,根据每次产生订单诞生的对象占据多大内存计算出总共需要的CPU内存。如果对响应时间有限制,那么就需要用压力测试来测出一个合适的配置。

    b. 12306遭遇春节大规模抢票该如何支撑?

        简而言之就是分流:CDN>LVS>NGINX>业务系统。部署多个服务器,各个区域的请求访问各自区域的服务器,并且库存也分散存储在不同的服务器上,由一个服务器做统一调配,这是为了避免出现数据倾斜问题,一台服务器上的票很快卖完了,另一台库存却还很充足。一种可能的模型是:下单>减库存和订单(redis、kafka)同时异步进行>等待付款。

    9. JVM调优-优化环境

    (1) 场景一:有一个50万PV的资料类网站(从磁盘读取文档到内存),原服务器32位,1.5G的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了。 

    a. 为什么原网站比较慢?

        很多用户浏览数据,很多数据load到内存,内存不足,频繁GC,STW时间长,响应时间变慢。

    b. 为什么新服务器更卡顿?

        内存越大,FGC时间越长。

    c. 如何进行调优

        PS+PO换成PN+CMS或者G1

    (2) 场景二:系统CPU经常100%,如何调优?

        CPU经常100%表示一定有线程在占用系统资源:

        a. 找出哪个进程CPU高 (top)

        b. 该进程中哪个线程CPU高 (top -Hp)

        c. 导出该线程的堆栈(jstack)

        d. 查找出哪个方法(栈帧)消耗最高(jstack)

    (3) 场景三:系统内存飙高,如何查找问题?

        a. 导出堆内存 (jmap)

        b. 分析(jhat  jvisualvm  jprofiler)

    10. jdk自带的常用工具

    (1) top命令

    

        观察哪个进程CPU占用率居高不下,如下图:

        我们再利用top -Hp 1502获取这个进程下所有线程的信息,如下图:

        我们可以看到编号为1519的线程占比CPU最高。

    (2) jps命令

        列出所有的java进程。如下图:

    

    (3) jstack命令

        jstack 25308会打印出所有线程的相信信息,如下图:

        根据所有线程的详细信息,我们就可以看到这些线程的状态,重点需要关注WATING、BLOCKED。

        由于线程很多,在排查问题时就不好定位。所以阿里巴巴开发者手册上规定,线程的名称(尤其是线程池)都要写有意义的名称。

        举例:waiting on <0x0000000088ca3310> (a java.lang.Object) 就表示在等待获取一个java.lang.Object的琐。假如有很多进程都在waiting on <xx>,那么需要我们搜索stack dump的信息,找到哪个线程持有这把锁处于RUNNABLE。

    (4) jinfo pid

        显示指定线程的详细信息,如下图:

    (5) jstat -gc

        打印指定线程的GC信息,如下:

        动态观察GC情况。jstat -gc 4655 500:每500毫秒打印一次GC的情况。

        但是这种方式所打印出的信息还是不够直观的,我们也可以利用jconsole.exe来连接进程来观察这个进程的相关信息,如下图:

    

        jconsole.exe的工具图形界面不够美观,我们也可以使用jvisualvm.exe来连接进程观察详细信息,如下图:

    图形界面一般不直接在线上环境上使用,会影响系统运行。在线跟踪还是推荐 arthas 。图形界面一般用在测试阶段,对系统进行压力测试、监控问题排查等。

    (6) jmap -histo 4655 | head -20

        显示进程4655的前17个数量对多的对象(有3行显示别的内容),如下图:

        显示了有哪些类哪些对象占用了多少个字节等。

        如果是线上系统排查问题,内存特别大的时候,jmap执行期间会对进程产生很大的影响,甚至卡顿。所以我们处理方式有以下几种:

            a. 设定参数HeapDump,OOM的时候会自动产生堆转储文件。

            b. 做高可用,有很多服务器,停掉一台对其他服务器不影响,也不影响系统使用。

            c. arthas 在线定位问题。

三、总结

    本文主要是介绍了一些参数来进行GC日志的打印阅读,介绍了JVM调优的基础概念以及一些小的调优场景,下一篇我们将针对各种实战场景了解更多的JVM调优所使用到的工具等。

    更多精彩内容,敬请扫描下方二维码,关注我的微信公众号【Java觉浅】,获取第一时间更新哦!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java觉浅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值