当前位置: 首页 > article >正文

JVM性能调优:从定位问题到解决——线上CPU 100%怎么办?

上回说到 并发锁有个小伙伴问”老师生产环境CPU 100%接口响应超时该如何排查”这让我想起了小王的一次线上事故——大促期间服务CPU飙到100%接口响应时间从500ms飙升到30s。今天我们就来聊聊 JVM性能调优从问题定位到解决方案。一、问题现场还原那是一个大促的晚上监控告警【紧急】订单服务CPU 100% 【紧急】接口响应时间 P99 30000ms 【紧急】Full GC频率1次/分钟小王赶紧登录服务器执行top命令PID USER PR NI VIRT RES %CPU %MEM TIME COMMAND 12345 appuser 20 0 3.2g 1.8g 100 45.2 2:30.52 javaCPU 100%这是什么情况二、问题排查步骤2.1 第一步找到占用CPU最高的线程# 1. 查看Java进程PID jps # 输出12345 OrderService # 2. 查看占用CPU最高的线程-H显示线程-p指定PID-n显示3次-d间隔1秒 top -H -p 12345 -n 3 -d 1 # 输出 PID USER PR NI VIRT RES %CPU %MEM TIME COMMAND 12348 appuser 20 0 3.2g 1.8g 89.5 45.2 1:25.30 java 12349 appuser 20 0 3.2g 1.8g 10.5 45.2 0:15.20 java 12350 appuser 20 0 3.2g 1.8g 0.0 45.2 0:00.00 java # 12348线程占用89.5%的CPU2.2 第二步将线程PID转换为16进制# 将12348转换为16进制 printf %x\n 12348 # 输出303c2.3 第三步查看线程堆栈# 查看线程堆栈-l打印锁信息 jstack 12345 | grep 303c -A 20 # 输出 pool-1-thread-1 #21 prio5 os_prio0 tid0x00007f8c5c012800 nid0x303c runnable [0x00007f8c52016000] java.lang.Thread.State: RUNNABLE at java.util.HashMap$TreeNode.transfer(HashMap.java:2015) at java.util.HashMap.resize(HashMap.java:703) at java.util.HashMap.putVal(HashMap.java:662) at java.util.HashMap.put(HashMap.java:611) at com.example.service.OrderService.processOrder(OrderService.java:125) at com.example.controller.OrderController.createOrder(OrderController.java:45)发现问题线程卡在HashMap.resize()上2.4 第四步分析问题// 问题代码 public class OrderService { private MapLong, Order orderCache new HashMap(); public void processOrder(Order order) { // 大量并发调用put导致HashMap扩容 orderCache.put(order.getId(), order); } }问题原因HashMap不是线程安全的多线程并发put会导致死循环JDK 1.7或者导致CPU 100%JDK 1.8扩容导致三、解决方案3.1 方案一使用ConcurrentHashMap推荐public class OrderService { // 使用ConcurrentHashMap替代HashMap private MapLong, Order orderCache new ConcurrentHashMap(); public void processOrder(Order order) { orderCache.put(order.getId(), order); } }3.2 方案二使用synchronizedpublic class OrderService { private MapLong, Order orderCache new HashMap(); public synchronized void processOrder(Order order) { orderCache.put(order.getId(), order); } }3.3 方案三使用Collections.synchronizedMappublic class OrderService { private MapLong, Order orderCache Collections.synchronizedMap(new HashMap()); public void processOrder(Order order) { orderCache.put(order.getId(), order); } }四、常见JVM问题及解决方案4.1 问题一内存溢出OOM现象java.lang.OutOfMemoryError: Java heap space排查步骤# 1. 查看JVM参数 jps -v # 输出12345 OrderService -Xms1g -Xmx1g # 2. 查看堆内存使用情况 jmap -heap 12345 # 3. 导出堆dump文件 jmap -dump:formatb,fileheap.hprof 12345 # 4. 使用MAT分析dump文件 # 下载地址https://www.eclipse.org/mat/解决方案# 调整JVM堆内存大小 java -Xms2g -Xmx2g -jar app.jar # 或者 java -XX:UseG1GC -Xms2g -Xmx2g -jar app.jar4.2 问题二内存泄漏现象堆内存持续增长Full GC频繁最终OOM常见原因// 原因1静态集合 public class MemoryLeakDemo { private static ListObject cache new ArrayList(); // 永不释放 public void add(Object obj) { cache.add(obj); } } // 原因2未关闭的资源 public void readFile() { InputStream is new FileInputStream(file.txt); // 忘记关闭is } // 原因3ThreadLocal未清理 public class ThreadLocalDemo { private static ThreadLocalObject threadLocal new ThreadLocal(); public void set(Object obj) { threadLocal.set(obj); // 线程结束后未清理导致内存泄漏 } }解决方案// 解决方案1使用弱引用 private static MapObject, Object cache new WeakHashMap(); // 解决方案2使用try-with-resources try (InputStream is new FileInputStream(file.txt)) { // 使用is } catch (IOException e) { e.printStackTrace(); } // 解决方案3ThreadLocal使用后清理 threadLocal.set(obj); try { // 使用threadLocal } finally { threadLocal.remove(); // 清理 }4.3 问题三频繁Full GC现象[Full GC (Allocation Failure) [PSYoungGen: 2048K-0K(2560K)] [ParOldGen: 69632K-69632K(69632K)]排查步骤# 查看GC日志 tail -f /var/log/gc.log # 查看GC统计信息 jstat -gcutil 12345 1000 10解决方案# 1. 使用G1垃圾收集器推荐 java -XX:UseG1GC -Xms2g -Xmx2g -jar app.jar # 2. 调整年轻代和老年代比例 java -Xms2g -Xmx2g -XX:NewRatio2 -jar app.jar # 3. 调整 survivor 比例 java -Xms2g -Xmx2g -XX:SurvivorRatio8 -jar app.jar五、JVM参数调优5.1 核心参数# 堆内存 -Xms2g # 初始堆大小 -Xmx2g # 最大堆大小 # 年轻代 -Xmn1g # 年轻代大小 -XX:NewRatio2 # 年轻代与老年代比例2:1 -XX:SurvivorRatio8 # Eden与Survivor比例8:1 # 垃圾收集器 -XX:UseG1GC # 使用G1推荐 -XX:UseParallelGC # 使用Parallel GC -XX:UseConcMarkSweepGC # 使用CMSJDK 14已废弃 # GC日志 -Xlog:gc*:filegc.log:time,tags:filecount5,filesize10m # 其他 -XX:MaxDirectMemorySize1g # 直接内存大小 -XX:MetaspaceSize256m # 元空间大小5.2 不同场景的推荐参数# 场景1中小型应用1-2GB内存 java -Xms1g -Xmx1g -XX:UseG1GC -jar app.jar # 场景2大型应用4-8GB内存 java -Xms4g -Xmx4g -XX:UseG1GC -XX:MaxGCPauseMillis200 -jar app.jar # 场景3高并发应用16GB内存 java -Xms8g -Xmx8g -XX:UseG1GC -XX:MaxGCPauseMillis200 -XX:ParallelGCThreads8 -jar app.jar六、监控工具6.1 JDK自带工具# jps查看Java进程 jps -v # jstat查看JVM统计信息 jstat -gcutil pid 1000 10 # jmap查看堆内存 jmap -heap pid # jstack查看线程堆栈 jstack pid # jcmd多功能工具 jcmd pid VM.flags jcmd pid GC.heap_info6.2 第三方工具工具用途下载地址Arthas在线诊断https://arthas.aliyun.com/VisualVM监控分析https://visualvm.github.io/MAT内存分析https://www.eclipse.org/mat/JProfiler性能分析https://www.ej-technologies.com/products/jprofiler/七、Arthas实战7.1 安装Arthas# 下载 curl -O https://arthas.aliyun.com/arthas-boot.jar # 启动 java -jar arthas-boot.jar # 选择进程 [INFO] arthas-boot version: 3.7.1 [INFO] Found existing java process, please choose one and hit RETURN. * [1]: 12345 OrderService7.2 常用命令# 查看线程 thread thread -n 3 # 查看CPU占用最高的3个线程 # 查看类加载 sc -d *Order* # 查看方法调用 monitor -c 5 com.example.OrderService processOrder # 查看堆栈 stack com.example.OrderService processOrder # 查看属性 getstatic com.example.OrderService cache # 热更新代码 jad --source-only com.example.OrderService /tmp/OrderService.java mc /tmp/OrderService.java redefine /tmp/OrderService.class八、性能调优清单✅ JVM调优检查清单 ├── 1. 是否设置了合理的堆内存大小 │ └── 建议Xms和Xmx设置相同值避免动态扩容 ├── 2. 是否选择了合适的垃圾收集器 │ └── 建议G1通用、Parallel高吞吐、ZGC低延迟 ├── 3. 是否开启了GC日志 │ └── 建议Xlog:gc*:filegc.log ├── 4. 是否有内存泄漏 │ └── 建议定期使用MAT分析dump文件 ├── 5. 是否有死锁 │ └── 建议jstack检测死锁 ├── 6. 是否有频繁Full GC │ └── 建议调整堆大小或垃圾收集器参数 └── 7. 是否有CPU 100% └── 建议top jstack定位问题线程九、总结今天我们学到了要点说明CPU 100%top jstack定位问题线程内存溢出jmap MAT分析dump文件内存泄漏静态集合、未关闭资源、ThreadLocal频繁Full GC调整堆大小、选择合适的GCJVM参数Xms/Xmx、垃圾收集器、GC日志监控工具jps/jstat/jmap/jstack、Arthas彩蛋小王用ConcurrentHashMap替代HashMap后CPU从100%降到20%接口响应时间恢复正常。他在群里发消息“HashMap就像多人抢厕所——谁先进去谁先上不排队容易打架。ConcurrentHashMap就像智能厕所——有多个隔间还有排队系统秩序井然”

相关文章:

JVM性能调优:从定位问题到解决——线上CPU 100%怎么办?

上回说到并发锁,有个小伙伴问:”老师,生产环境CPU 100%,接口响应超时,该如何排查?”这让我想起了小王的一次线上事故——大促期间,服务CPU飙到100%,接口响应时间从500ms飙升到30s。今…...

阿里云社招一面:数据库中有 1000 万数据的时候怎么分页查询?

今天给大家分享一道阿里云社招面试中的经典问题——如何处理千万级数据的分页查询。这不仅是高频面试题,更是实际业务中必须解决的性能难题。下面我会从基础实现到阿里级优化方案,逐步拆解这个问题的技术要点。 1. 基础方案:LIMIT OFFSET的致…...

Windows系统优化终极指南:Chris Titus Tech WinUtil一键搞定所有系统管理

Windows系统优化终极指南:Chris Titus Tech WinUtil一键搞定所有系统管理 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil Windows…...

魔兽世界API开发终极指南:3分钟掌握wow_api完整使用技巧

魔兽世界API开发终极指南:3分钟掌握wow_api完整使用技巧 【免费下载链接】wow_api Documents of wow API -- 魔兽世界API资料以及宏工具 项目地址: https://gitcode.com/gh_mirrors/wo/wow_api wow_api是一个专为《魔兽世界》开发者和玩家设计的开源工具集&a…...

【无人机三维路径规划】改进灰狼算法I-GWO多策略融合的无人机UAV路径规划【含Matlab源码 15377期】

💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab武动乾坤博客之家💞…...

解锁学术新秘籍:书匠策AI——期刊论文的“全能魔法师”

在学术的广袤天地里,期刊论文宛如璀璨星辰,照亮着知识探索的漫漫征途。对于莘莘学子、科研先锋以及学术追梦人而言,发表一篇高质量的期刊论文,不仅是展示自身才华与研究成果的绝佳舞台,更是推动学术进步、实现个人价值…...

解锁论文秘籍:书匠策AI——期刊论文创作的“智慧锦囊”

在学术的征途上,期刊论文是每一位研究者展示智慧结晶、推动学科进步的重要载体。然而,从选题构思到最终成稿,每一步都充满了挑战,让不少学者和学生倍感压力。别担心,今天我们就来揭秘一个强大的学术助手— 书匠策AI官网…...

揭秘书匠策AI:毕业论文写作的“全能魔法师”现身!

在学术的广阔天地里,毕业论文就像是一场盛大的探险,既充满挑战也蕴含无限可能。每一位踏上这场探险之旅的学子,都渴望拥有一位得力的向导,让前行的道路更加顺畅。今天,就让我带你走进书匠策AI的世界,这位毕…...

解锁学术新姿势:书匠策AI——期刊论文的“全能魔法师”

在学术探索的征途中,期刊论文是每位学者展示智慧火花的舞台,也是知识传承与创新的重要载体。然而,面对堆积如山的文献、错综复杂的逻辑结构,以及那令人头疼的格式要求,不少学者尤其是初学者常常感到力不从心。别怕&…...

银行金融机构专利数据2003-2023年

01、数据介绍金融机构作为申请主体,在科技创新过程中形成的具有新颖性、创造性和实用性的技术方案,并通过法定程序向国家专利局提出专利申请,经审查合格后被授予的专利权。金融机构的机构申请数量占比总银行数量不足5%,却贡献了76…...

3D打印Cherry MX键帽:从设计到制造的完整开源方案

3D打印Cherry MX键帽:从设计到制造的完整开源方案 【免费下载链接】cherry-mx-keycaps 3D models of Chery MX keycaps 项目地址: https://gitcode.com/gh_mirrors/ch/cherry-mx-keycaps 你是否曾经为找不到特殊尺寸的键帽而烦恼?或者想为自己的机…...

windows在使用ping 127.0.0.1时出现一般故障的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

AI开发安全隔离新范式(Docker Sandbox企业级配置全图谱)

更多请点击: https://intelliparadigm.com 第一章:AI开发安全隔离新范式(Docker Sandbox企业级配置全图谱) 在AI模型快速迭代与多团队协同开发场景下,传统共享环境极易引发依赖冲突、权限越界与训练数据泄露风险。Doc…...

VS Code MCP插件权限控制实战:5步构建SBOM+OPA双引擎合规防护体系

更多请点击: https://intelliparadigm.com 第一章:VS Code MCP插件权限控制实战:5步构建SBOMOPA双引擎合规防护体系 VS Code 的 MCP(Model Context Protocol)插件在 AI 原生开发中日益关键,但其对本地文件…...

终极指南:如何在电脑上流畅控制安卓手机的完整教程

终极指南:如何在电脑上流畅控制安卓手机的完整教程 【免费下载链接】QtScrcpy Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScrcpy …...

XUnity.AutoTranslator:如何让外语游戏瞬间变成你的母语?

XUnity.AutoTranslator:如何让外语游戏瞬间变成你的母语? 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而错过精彩的游戏剧情?面对日语、英语…...

终极解放!MAA明日方舟助手如何让你每天节省3小时游戏时间?

终极解放!MAA明日方舟助手如何让你每天节省3小时游戏时间? 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地…...

Snap.Hutao开源原神工具箱:一站式解决Windows玩家的游戏管理痛点

Snap.Hutao开源原神工具箱:一站式解决Windows玩家的游戏管理痛点 【免费下载链接】Snap.Hutao 实用的开源多功能原神工具箱 🧰 / Multifunctional Open-Source Genshin Impact Toolkit 🧰 项目地址: https://gitcode.com/GitHub_Trending/s…...

终极指南:如何快速解码Adobe JSXBIN加密脚本

终极指南:如何快速解码Adobe JSXBIN加密脚本 【免费下载链接】jsxer A fast and accurate JSXBIN decompiler. 项目地址: https://gitcode.com/gh_mirrors/js/jsxer 在Adobe创意套件生态系统中,JSXBIN格式是保护ExtendScript脚本知识产权的常见方…...

Visual C++运行库一键修复终极指南:三步解决Windows系统依赖问题

Visual C运行库一键修复终极指南:三步解决Windows系统依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的困扰&#xff…...

学习自律养成系统小程序|基于java+小程序的学习自律养成小程序设计与实现(源码+数据库+文档)

学习自律养成小程序 目录 基于java小程序的学习自律养成小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&…...

PTA天梯赛L2真题保姆级复盘:L2-047锦标赛与L2-048寻宝图的DFS/二叉树实战避坑指南

PTA天梯赛L2级算法实战精要:从二叉树重构到矩阵DFS的竞赛思维突破 在算法竞赛的进阶之路上,PTA天梯赛L2级别的题目往往成为区分选手能力的关键分水岭。特别是涉及复杂数据结构与高效算法结合的题目,如完美二叉树重构和大规模矩阵DFS遍历&…...

终极iOS 15-16 iCloud绕过教程:applera1n工具完整使用指南

终极iOS 15-16 iCloud绕过教程:applera1n工具完整使用指南 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 你是否遇到过iPhone或iPad因iCloud激活锁而无法使用的困境?当你恢复出…...

手把手教你配置RH850U2A的MPU:从寄存器操作到异常处理(附代码示例)

手把手教你配置RH850U2A的MPU:从寄存器操作到异常处理(附代码示例) 在嵌入式系统开发中,内存保护单元(MPU)是确保系统稳定性和安全性的关键组件。对于使用瑞萨RH850U2A系列MCU的开发者来说,正确配置MPU不仅能防止内存越…...

类加载器、双亲委派机制是干啥的?一文详解

目录 一.类加载器 1.作用:加载class文件 举例 2.过程详解 代码示例 3.类加载器的种类 ①启动类(根)加载器(Bootstrap ClassLoader,爷爷) ②扩展类加载器(Extension ClassLoader,爸爸) ③应用程序加载器(Appli…...

G-Helper:重新定义华硕笔记本硬件控制的轻量化解决方案

G-Helper:重新定义华硕笔记本硬件控制的轻量化解决方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, S…...

Vue ECharts构建优化终极指南:从2.8MB到300KB的实战深度解析

Vue ECharts构建优化终极指南:从2.8MB到300KB的实战深度解析 【免费下载链接】vue-echarts Vue.js component for Apache ECharts™. 项目地址: https://gitcode.com/gh_mirrors/vu/vue-echarts Vue ECharts作为Vue.js生态中最强大的数据可视化组件库之一&am…...

3分钟解决Visual C++运行库问题:AIO一键修复工具终极指南

3分钟解决Visual C运行库问题:AIO一键修复工具终极指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库缺失或损坏是Windows系统中最常…...

5个CS2游戏增强功能:Osiris跨平台辅助工具完全指南

5个CS2游戏增强功能:Osiris跨平台辅助工具完全指南 【免费下载链接】Osiris Cross-platform game hack for Counter-Strike 2 with Panorama-based GUI. 项目地址: https://gitcode.com/gh_mirrors/os/Osiris Osiris是一款专为《反恐精英2》(CS2&…...

5分钟掌握WenQuanYi Micro Hei:轻量级开源中文字体安装完全指南

5分钟掌握WenQuanYi Micro Hei:轻量级开源中文字体安装完全指南 【免费下载链接】fonts-wqy-microhei Debian package for WenQuanYi Micro Hei (mirror of https://anonscm.debian.org/git/pkg-fonts/fonts-wqy-microhei.git) 项目地址: https://gitcode.com/gh_…...