1. 性能剖析基础:什么是性能剖析、为什么需要性能剖析、性能剖析的常见指标

大家好,我是你们这门课的老朋友。今天咱们聊聊性能剖析的基础。说实话,我刚开始做开发那会儿,对性能这事儿真没太当回事。直到有一次线上服务在高峰期直接挂了,老板黑着脸站在我工位旁边……嗯,从那以后,性能剖析就成了我的必修课。

什么是性能剖析?

性能剖析,说白了就是给程序做体检。你想想看,人每年都要体检,看看血压高不高、血脂稠不稠。程序也一样,它跑得慢、吃内存、狂写磁盘,总得有个工具帮我们查清楚到底哪里出了问题。

我个人习惯把性能剖析分成两类:

  • 采样型剖析:每隔一小段时间拍一张快照,看看CPU正在执行什么代码。就像监控摄像头,隔几秒拍一张,最后拼出完整画面。
  • 插桩型剖析:在代码的关键位置埋点,记录每次函数调用的耗时、次数。这更像是在跑道上装计时器,每个运动员经过时都记一笔。

我在项目中遇到过一种情况:用采样型工具发现某个函数占用CPU很高,但换成插桩型一测,发现其实调用次数极少,只是单次执行特别慢。两种方法各有侧重,搭配使用效果最好。

核心要点:性能剖析不是玄学,它是用数据说话的过程。没有数据支撑的优化,都是瞎猜。

为什么需要性能剖析?

这个问题我问过不少新人,答案五花八门。有人说「为了优化速度」,有人说「为了省服务器钱」。都对,但不够全面。

我总结了几条必须做性能剖析的理由:

  1. 定位瓶颈:程序慢,到底慢在哪?是数据库查询太慢,还是网络请求阻塞,还是算法效率低?没有剖析,你只能靠猜。
  2. 避免过度优化:你花三天优化了一段代码,结果它只占整体运行时间的0.1%。这时间花得值吗?剖析能告诉你该把精力放在哪。
  3. 容量规划:线上需要多少台服务器?剖析数据能给出靠谱的估算,而不是拍脑袋。
  4. 排查异常:内存泄漏、CPU飙升、IO打满……这些线上事故,没有剖析工具你根本无从下手。

我的经验:我曾经接手过一个老项目,代码里到处都是「优化」,结果一剖析发现90%的时间花在日志打印上。你说这找谁说理去?所以记住:先剖析,再优化,顺序别搞反。

性能剖析的常见指标

指标这东西,说白了就是你要看哪些数据。我一般关注四个维度:CPU、内存、IO、网络。下面这张图能帮你快速建立整体认知:

性能剖析 四大核心指标 CPU 使用率 · 负载 · 上下文切换 关注:热点函数、线程争抢 内存 堆 · 栈 · GC · 泄漏 关注:对象分配、回收频率 IO 磁盘读写 · 吞吐 · 延迟 关注:随机读写、IO等待 网络 带宽 · 延迟 · 丢包 · 连接数 关注:请求排队、超时重传

CPU指标

CPU是程序的发动机。我一般先看这几个:

  • CPU使用率:用户态、内核态、IO等待各占多少。如果IO等待高,说明磁盘是瓶颈。
  • 上下文切换:频繁切换意味着线程太多或锁竞争激烈。
  • 热点函数:哪个函数吃掉了最多的CPU时间片。

注意:CPU使用率100%不一定就是坏事。如果你的程序就是做密集计算的,那100%反而是好事。关键要看「有效计算」和「无效等待」的比例。

内存指标

内存这块坑最多。我见过太多内存泄漏导致OOM的案例了。

  • 堆内存使用:对象分配速率、存活对象大小。
  • GC频率和停顿:GC太频繁说明内存紧张或对象创建太多。
  • 内存泄漏:老年代持续增长,最终撑爆。

我曾经排查过一个Java服务,内存曲线像爬楼梯一样只升不降。用heap dump一分析,发现有个缓存Map只put不remove,数据越积越多。修复后内存直接降了60%。

IO指标

IO往往是性能瓶颈的「隐形杀手」。CPU和内存的问题容易发现,但IO问题经常被忽略。

  • 磁盘吞吐:每秒读写多少MB。
  • IO延迟:每次读写平均耗时。
  • IOPS:每秒读写次数。小文件随机读写尤其关注这个。

你想想看,一个日志打印操作,如果每次都要刷盘,高并发下磁盘IO直接被打满。我见过一个项目,把日志级别从DEBUG改成INFO,吞吐量直接翻倍。原因就是少写了大量磁盘。

网络指标

微服务架构下,网络问题越来越突出。

  • 带宽使用率:是否接近网卡上限。
  • 延迟:请求从发出到收到响应的时间。
  • 连接数:TIME_WAIT、CLOSE_WAIT状态是否异常。
  • 丢包率:重传比例高说明网络质量差。

一个小技巧:我习惯用ss -s快速查看当前系统的socket统计。如果TIME_WAIT超过几万个,那基本可以断定连接池配置有问题。

指标之间的关系

这四个指标不是孤立的。CPU高可能是因为内存不足导致频繁GC;IO慢可能是因为网络带宽被占满。所以做性能剖析时,我建议你综合看,别只盯一个维度。

现象 可能原因 优先排查
CPU高、响应慢 热点函数、GC频繁、锁竞争 CPU剖析 + 线程dump
内存持续增长 内存泄漏、缓存过大 heap dump分析
IO等待高 磁盘慢、日志太多、文件读写频繁 iostat + strace
网络延迟高 带宽不足、连接池耗尽、DNS解析慢 ping + tcpdump + netstat

好了,这一章的内容就到这里。性能剖析的基础概念和核心指标咱们都过了一遍。记住一句话:没有数据,就没有优化。下一章咱们会深入实战,拿真实代码开刀,看看这些指标到底怎么用。

想要更多资料,联系可可