尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

性能分析四件套:从死锁到CPU瓶颈全解析!

性能分析四件套:从死锁到CPU瓶颈全解析! 全文目录开篇语0. 前言谁还没被性能问题折磨过1. jstack死锁线程卡死它就是你的“线程抓捕专家” 场景解决线程阻塞、死锁、CPU 飙高问题️ 实战操作 如何分析 jstack.log2. jmap内存泄漏堆溢出它就是你的“内存 X光机” 场景解决内存泄漏、OOM、GC 频繁问题️ 实战操作3. jstatGC 监控类加载它就是你的“JVM 仪表盘” 场景定位 GC 性能瓶颈、内存区域使用情况️ 实战操作4. async-profiler谁在偷偷吃我的 CPU它就是你的“性能外科医生” 场景定位 CPU 瓶颈、热点方法、I/O 阻塞、内存分配热点️ 实战操作5. 写在最后工欲善其事必先利其器文末开篇语哈喽各位小伙伴们你们好呀我是喵手。运营社区C站/掘金/腾讯云/阿里云/华为云/51CTO欢迎大家常来逛逛今天我要给大家分享一些自己日常学习到的一些知识点并以文字的形式跟大家一起交流互相学习一个人虽可以走的更快但一群人可以走的更远。我是一名后端开发爱好者工作日常接触到最多的就是Java语言啦所以我都尽量抽业余时间把自己所学到所会的通过文章的形式进行输出希望以这种方式帮助到更多的初学者或者想入门的小伙伴们同时也能对自己的技术进行沉淀加以复盘查缺补漏。小伙伴们在批阅的过程中如果觉得文章不错欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持0. 前言谁还没被性能问题折磨过性能问题对于咱们程序员来说简直就是“魔鬼的考验”。 表面上看程序运行得好好的但一旦遇到高并发、大数据量立马就“原形毕露”。系统响应慢、CPU 居高不下、内存飙升、莫名其妙的线程阻塞……这些都是咱们加班的元凶更气人的是这种 Bug 往往在开发环境根本测不出来只有在生产环境在用户眼皮底下才跳出来给你一个“惊喜”所以掌握性能分析工具就如同医生掌握了诊断病症的仪器。你不能光靠经验拍脑袋你得有数据有证据今天我就带大家领略一下jstack、jmap、jstat、async-profiler的魅力。这可不是简单的命令行教程咱们要结合实际场景看看它们到底能帮你解决什么鬼畜问题1. jstack死锁线程卡死它就是你的“线程抓捕专家”jstack全称Java Stack Trace顾名思义它主要用来打印 JVM 进程中所有线程的栈轨迹stack trace。它的作用就像什么呢就像你在公司年会玩“定格游戏”突然主持人喊“Freeze”所有人都得停下来保持那一瞬间的动作。jstack 就是那个主持人它能让你看到 JVM 中每个线程在某一瞬间都在干啥。‍♀️ 场景解决线程阻塞、死锁、CPU 飙高问题线程阻塞某个线程卡在某个方法调用上或者等待某个锁导致整个请求响应慢。死锁两个或多个线程互相持有对方所需的资源谁也无法继续执行永久阻塞。CPU 飙高某个线程陷入了死循环或者在执行大量计算导致 CPU 负载过高。️ 实战操作找到你的 Java 进程 ID (PID)ps-ef|grepjava# 或者jps-l假设你的 PID 是12345。生成线程堆栈jstack12345jstack.log注意建议多采集几次每次间隔几秒比如三次jstack12345jstack1.logsleep5jstack12345jstack2.logsleep5jstack12345jstack3.log这样做的目的是如果某个线程只是偶尔卡顿或者在等待资源通过多次采样就能看出它的“轨迹”。如果是死循环或者死锁那么在多次采样中它都会停留在同一个地方。 如何分析jstack.log看BLOCKED、WAITING、TIMED_WAITING状态这些状态说明线程在等待。BLOCKED (on object monitor)线程正在等待获取一个对象锁。WAITING (on object monitor)线程调用了Object.wait()或LockSupport.park()等方法正在等待被唤醒。TIMED_WAITING类似 WAITING但有超时时间。寻找deadlockjstack 会自动帮你检测死锁并高亮出来这简直是福尔摩斯本人✨CPU 占用高的线程结合top -Hp PID命令找到 CPU 最高的线程 ID然后将该线程 ID 转换为 16 进制在 jstack 文件中搜索。你就能看到这个“捣蛋鬼”正在执行哪个方法小结jstack 就是你的“透视眼”能一眼看穿线程在干嘛。当程序卡顿没有响应时首先想到的就是它2. jmap内存泄漏堆溢出它就是你的“内存 X光机”jmap全称Java Memory Map。它主要用来生成 JVM 堆内存的快照Heap Dump分析内存中的对象情况。它的作用就像什么呢就像你拍了一张照片把内存里所有的对象、它们之间互相引用关系都“定格”下来。然后你可以用专业的工具如 Eclipse MAT 或 JProfiler来分析这张照片。 场景解决内存泄漏、OOM、GC 频繁问题内存泄漏 (Memory Leak)对象创建后不再使用但由于被某些引用链条“活生生”地拽着GC 无法回收导致内存不断上涨。OOM (OutOfMemoryError)内存不足程序崩溃。GC 频繁由于内存占用过高或分配不合理导致 GC 频繁执行系统卡顿。️ 实战操作找到你的 Java 进程 ID (PID)同 jstack生成堆内存快照jmap-dump:formatb,fileheap.hprof12345formatb指定输出格式为二进制这是标准的堆转储文件格式。fileheap.hprof指定输出文件名。注意生成堆转储文件时JVM 会暂停STW尤其是在堆内存很大的情况下可能会暂停几十秒甚至几分钟所以在生产环境谨慎操作最好选择业务低峰期。分析堆转储文件将heap.hprof文件下载到本地用Eclipse Memory Analyzer Tool (MAT)或者JProfiler打开。MAT可以帮你找到最大的对象、哪个对象占用内存最多、哪个对象是 GC Root 等等。它还有强大的“Path To GC Roots”功能能帮你分析为什么某个对象没有被回收。这简直就是你的“内存侦探”小结jmap 帮你把内存挖出来让你看到所有对象的真实面貌和关系网。是解决内存问题的终极武器3. jstatGC 监控类加载它就是你的“JVM 仪表盘”jstat全称JVM Statistics Monitoring Tool。它是一个非常轻量级的命令行工具用来实时监控 JVM 各种运行状态信息包括类加载、GC 行为、JIT 编译等。它的作用就像什么呢就像汽车的仪表盘 你可以实时看到油耗GC 频率、发动机转速类加载、车速JIT 编译等各种参数而不会对汽车本身造成任何负担。 场景定位 GC 性能瓶颈、内存区域使用情况GC 频繁或耗时过长导致系统卡顿。内存区域新生代、老年代分配不合理导致内存利用率低或 GC 压力大。Full GC 频繁这通常是老年代内存不足的信号。️ 实战操作找到你的 Java 进程 ID (PID)同 jstack实时监控 GC 情况jstat-gcutil12345100010-gcutil显示 GC 统计信息推荐最常用。12345进程 ID。1000每隔 1000 毫秒1秒刷新一次。10总共刷新 10 次。输出示例S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 12.56 90.23 98.76 96.54 10 0.123 1 0.045 0.168 0.00 0.00 20.34 90.23 98.76 96.54 10 0.123 1 0.045 0.168 ...关键字段EEden 区使用百分比。OOld 区老年代使用百分比。YGCYoung GC 次数。YGCTYoung GC 总耗时。FGCFull GC 次数。FGCTFull GC 总耗时。GCT所有 GC 总耗时。监控堆内存jstat-gc12345100010-gc显示堆内存使用情况KBytes。小结jstat 是你的“雷达”能够实时发现 GC 和内存使用的异常。当你怀疑是 GC 导致卡顿或者内存分配不合理时jstat 是第一手资料的来源。4. async-profiler谁在偷偷吃我的 CPU它就是你的“性能外科医生”async-profiler是这四个工具里的“新星”和“黑科技”⭐ 它是一个低开销的、能采样的、非侵入式的 JVM 性能分析工具。它能够以非常低的开销通常低于 1%生成 CPU 火焰图、内存火焰图、锁火焰图等帮助你快速定位热点代码。它的作用就像什么呢就像一个专业的“性能外科医生”它能精准地切割出你的程序里最消耗 CPU、内存或者 I/O 的那块“病灶”并用火焰图 (Flame Graph)的形式直观地展现出来。 场景定位 CPU 瓶颈、热点方法、I/O 阻塞、内存分配热点CPU 占用过高找出哪个方法、哪行代码导致了 CPU 狂飙。方法调用链分析哪个函数调用了哪个函数最终导致了性能问题。GC 频繁找到频繁创建对象的“罪魁祸首”。I/O 阻塞分析网络 I/O、磁盘 I/O 等待耗时。️ 实战操作下载 async-profiler# 例如gitclone https://github.com/jvm-profiling-tools/async-profiler.gitcdasync-profilermake# 编译启动你的 Java 应用并附加 async-profiler (或直接在运行时启动)# 方式一在 JVM 启动参数中添加java-agentpath:/path/to/async-profiler/build/libasyncProfiler.sostart,filecpu.svg,eventcpu,interval9ms,duration30s-jaryour_app.jar# 方式二在运行时动态 attach (推荐无需重启应用)# 首先找到 PID# 然后运行./profiler.sh-d30-fcpu.svg12345# -d 30: 采样 30 秒# -f cpu.svg: 输出到 cpu.svg 文件 (会生成火焰图)# 12345: 进程 ID分析火焰图cpu.svg用浏览器打开cpu.svg文件。宽度代表耗时占比越宽的“火焰”说明该方法或方法栈占用 CPU 时间越多。高度代表调用栈深度堆栈的每一层表示一个方法。顶部是“最热”方法顶部最宽的火焰通常就是需要优化的目标。小结async-profiler 及其生成的火焰图是当前最先进、最直观的性能瓶颈分析工具。它能让你从宏观到微观一览无余地看清程序的性能热点。简直是神器中的神器5. 写在最后工欲善其事必先利其器看到没这四个工具各有神通互相配合简直就是一套性能分析的“天团组合”jstat帮你宏观监控快速发现问题在哪里发生GC内存。jstack帮你微观定位发现是哪个线程在“磨洋工”死锁阻塞。jmap帮你深层挖掘找出是哪个对象在“吸血”内存泄漏OOM。async-profiler更是直接“手起刀落”帮你精准找到性能热点和代码瓶颈所以啊兄弟们别再做那个只会敲CtrlC、CtrlV的“CRUD 仔”了 把这些工具玩溜你就是团队里那个能“力挽狂澜”、拯救生产环境于水火之中的**“性能英雄”**‍♂️下次再遇到性能问题请记住我的话“别慌打开终端jstack走起”你会发现解决性能问题其实也挺上头的好了今天就聊到这儿。拿起你的键盘赶紧找个跑着的 Java 应用实战一下这些命令吧实践出真知✨… …文末好啦以上就是我这期的全部内容如果有任何疑问欢迎下方留言哦咱们下期见。… …学习不分先后知识不分多少事无巨细当以虚心求教三人行必有我师焉wished for you successed ⭐️若喜欢我就请关注我叭。⭐️若对您有用就请点赞叭。⭐️若有疑问就请评论留言告诉我叭。版权声明本文由作者原创转载请注明出处谢谢支持
返回列表