【Java性能调优】(性能调优流程)从系统评估到性能调优

本文详细介绍了Java性能调优的流程,从衡量系统现状、设定调优目标,到识别性能瓶颈,再到具体的CPU、IO、网络、JVM内存等问题的分析和解决方案。通过监控工具如top、pidstat、iostat等,针对CPU的us、sy值,以及内存和网络IO的消耗进行深入剖析,提出减少上下文切换、异步处理、批量操作和限流等优化策略,帮助Java开发者提升应用性能。
摘要由CSDN通过智能技术生成

这里写目录标题

调优的流程

调优前首先要做的是 衡量系统现状 ,这包括目前系统的请求次数、响应时间、资源消耗等信息,例如A系统目前95%的请求响应时间为1秒。

在有了系统现状后可 设定调优目标 ,通常调优目标是根据用户所能接受的响应速度或系统所拥有的机器以及所支撑的用户量制定出来的,因此通常会设定出调优目标:95%的请求要在500ms 内返回。

在设定了调优的目标后,需要做的是 寻找出性能瓶颈 ,这一步最重要的是找出造成目前系统性能不足的最大瓶颈点。找出后,可结合一些工具来找出造成瓶颈点的代码,到此才完成了这个步骤。

在寻找到了造成瓶颈点的代码后,通常需要 分析其需求场景 ,然后结合一些优化的技巧 制定优化的策略 。优化策略或简或繁,选择其中收益比(优化后的预期效果/优化需要付出的代价)最高的优化方案,进行优化。

优化部署后, 继续衡量系统的状况 ,如已达到目标,则可结束此次调优;如仍未达到目标,则要看是否产生了新的性能瓶颈。或可以考虑继续尝试上一步中制定的其他优化方案,直到达成调优目标或论证在目前的体系结构上无法达成调优目标为止。

CPU类问题

概念

  1. 上下文切换

每个CPU(或多核CPU中的每核CPU)在同一时间只能执行一个线程 ,Linux采用的是抢占式调度。即为每个线程分配一定的执行时间,当到达执行时间、线程中有IO阻塞或高优先级线程要执行时,Linux将 切换执行的线程 , 在切换时要存储目前线程的执行状态,并恢复要执行的线程的状态,这个过程就称为上下文切换 。对于Java应用,典型的是在进行文件IO操作、网络IO操作、锁等待或线程Sleep时,当前线程会进入阻塞或休眠状态,从而触发上下文切换,上下文切换过多会造成内核占据较多的CPU使用,使得应用的响应速度下降。

  1. 运行队列

每个CPU核都维护了一个可运行的线程队列,例如一个4核的CPU,Java应用中启动了8个线程,且这8个线程都处于可运行状态,那么在分配平均的情况下每个CPU中的运行队列里就会有两个线程。通常而言,系统的load主要由CPU的运行队列来决定,假设以上状况维持了1分钟,那么这1分钟内系统的load就会是2,但由于load是个复杂的值3,因此也不是绝对的, 运行队列值越大,就意味着线程会要消耗越长的时间才能执行完 。Linux System and NetWork Performance Monitoring *中建议控制在每个CPU核上的运行队列为13个。

  1. 利用率

**CPU利用率为CPU在用户进程、内核、中断处理、IO等待以及空闲五个部分使用百分比,这五个值是用来分析CPU消耗情况的关键指标。**Linux System and NetWork Performance Monitoring 中建议用户进程的CPU 消耗/内核的CPU消耗的比率在65%~70%/30%~35%左右。

工具和指令

  1. top

在此需要关注的是第三行的信息,其中 4.0% us 表示 为用户进程处理所占的百分比 ;8.9% sy 表示为 内核线程处理所占的百分比 ;0.0% ni表示被nice 命令改变优先级的任务所占的百分比;87.0%id表示CPU的空闲时间所占的百分比;0.0% wa表示为在执行的过程中等待IO所占的百分比;0.2% hi表示为硬件中断所占的百分比;0.0% si表示为软件中断所占的百分比。

进入top后按1会按cpu核来显示消耗情况:

在TOP视图中按shift+h会按线程来显示消耗状况:

  1. pidstat

pidstat是SYSSTAT中的工具,如须使用pidstat,请先安装SYSSTAT5。

输入pidstat 1 2,在console上将会每隔1秒输出目前活动进程的CPU消耗状况,共输出2次,结果如图所示:

其中CPU表示的为当前进程所使用到的CPU个数。

如须查看某进程中线程的CPU消耗状况,可输入 pidstat -p [PID]-t 15 这样的方式来查看,执行后的输出如图所示:

图中的TID即为线程ID,较之top命令方式而言,pidstat 的好处为 可查看每个线程的具体CPU利用率的状况(例如%system)。

对于JAVA应用而言,最重要的消耗体现在us,sy这两个值上。

当us值过高时,表示运行的应用消耗了大部分的CPU。在这种情况下,对于Java应用而言,最重要的为找到具体消耗 CPU的线程所执行的代码,可采用如下方法做到。

首先通过linux提供的命令 找到消耗CPU严重的线程及其ID ,将此线程ID转化为十六进制的值。之后 通过kill -3 [javapid]或jstack 的方式 dump出应用的java线程信息,通过之前转化出的十六进制的值找到对应的nid值的线程 。该线程即为消耗CPU的线程,在采样时须多执行几次上述的过程,以确保找

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值