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

JVM调优实战:从垃圾回收到内存模型,一次性搞定JVM核心知识点

一、JVM内存模型(JMM)

1.1 运行时数据区

┌─────────────────────────────────────┐ │ 运行时数据区 │ ├───────────────┬─────────────────────┤ │ │ 方法区 │ │ 线程共享区域 │ │ │ │ 堆 │ ├───────────────┴─────────────────────┤ │ │ 虚拟机栈 │ │ 线程私有区域 │ │ │ │ 本地方法栈 │ │ │ │ │ │ 程序计数器 │ └─────────────────────────────────────┘

1.2 各区域作用

区域作用大小
程序计数器记录当前线程执行的字节码行号固定大小
虚拟机栈方法调用栈帧,存局部变量、操作数栈动态扩展/收缩
本地方法栈native方法调用动态扩展/收缩
对象实例、数组可通过-Xms/-Xmx调整
方法区类信息、常量、静态变量可通过-XX:MetaspaceSize调整

二、垃圾回收算法

2.1 引用计数法(不用)

// 每个对象有个引用计数器// 引用+1,失效-1// 问题:循环引用无法回收ObjectA=newObject();ObjectB=newObject();A.ref=B;B.ref=A;A=null;B=null;// A和B互相引用,但已经不可达,计数却不为0

2.2 可达性分析(Java用这个)

GC Roots对象: ├── 虚拟机栈中引用的对象 ├── 方法区中类静态属性引用的对象 ├── 方法区中常量引用的对象 ├── 本地方法栈中JNI引用的对象 └── 活跃的线程引用

2.3 四种引用类型

// 强引用(永远不会回收)Objectobj=newObject();// 软引用(内存不足时回收)SoftReference<Object>soft=newSoftReference<>(newObject());// 弱引用(下次GC时回收)WeakReference<Object>weak=newWeakReference<>(newObject());// 虚引用(无法通过虚引用获取对象)PhantomReference<Object>phantom=newPhantomReference<>(newObject(),refQueue);

三、垃圾回收器

3.1 垃圾回收器分类

┌────────────────────────────────────────────────────┐ │ 新生代(Minor GC) │ │ ───────────────────────────────────────────────── │ │ Serial(串行)│ ParNew(并行)│ Parallel Scavenge │ │ ↓ ↓ ↓ │ ├────────────────────────────────────────────────────┤ │ 老年代(Major/Full GC) │ │ Serial Old│ Parallel Old│ CMS │ G1 │ ZGC │ └────────────────────────────────────────────────────┘

3.2 各回收器对比

回收器线程策略适用场景
Serial单线程复制客户端模式
ParNew多线程复制多核服务端
Parallel Scavenge多线程复制吞吐量优先
CMS多线程并发标记-清除低延迟
G1多线程并发标记-整理大堆低延迟
ZGC多线程并发着色指针极低延迟(<1ms)

3.3 CMS回收器(重点)

CMS(Concurrent Mark Sweep)是一种并发执行的垃圾回收器:

初始标记(STW)→ 并发标记 → 重新标记(STW)→ 并发清除

CMS配置:

-XX:+UseConcMarkSweepGC-XX:CMSInitialMarkingThreshold=100-XX:ConcGCThreads=4-XX:CMSInitiatingOccupancyFraction=70

CMS问题:

  1. 内存碎片:标记-清除算法导致
  2. 浮动垃圾:并发标记时新产生的垃圾
  3. concurrent mode failure:浮动垃圾太多时触发

四、G1垃圾回收器

4.1 G1特点

特点说明
逻辑分代仍有新生代老年代概念
物理不分代内存是连续的小区块(Region)
可预测停顿可以设置停顿时间目标
整合多种算法复制+标记-整理

4.2 G1 Region

┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐ │ Eden ││ Eden ││ S1 ││ S2 ││ Old │ └──────┘└──────┘└──────┘└──────┘└──────┘ ↓ ↓ ↓ ┌──────────────────────────────────────┐ │ Humongous(大对象区) │ └──────────────────────────────────────┘

G1配置:

-XX:+UseG1GC-XX:MaxGCPauseMillis=200-XX:G1HeapRegionSize=4-XX:InitiatingHeapOccupancyPercent=45

五、JVM调优实战

5.1 常用JVM参数

# 堆大小设置-Xms4g# 初始堆大小-Xmx4g# 最大堆大小-Xmn2g# 新生代大小-Xss256k# 线程栈大小# 元空间设置-XX:MetaspaceSize=256m-XX:MaxMetaspaceSize=512m# GC日志-Xlog:gc*:file=gc.log

5.2 典型GC问题场景

场景1:频繁Young GC

现象:对象分配频繁,Survivor区不够 原因:对象朝生夕灭太多 解决: -Xmn1024m 调大新生代 -XX:MaxTenuringThreshold=15 调大年龄阈值

场景2:Full GC频繁

现象:老年代频繁回收 原因:大对象直接进老年代/内存泄漏 解决: -XX:+UseG1GC 换成G1 -XX:NewRatio=2 调小老年代比例 检查代码是否有内存泄漏

5.3 排查工具

# 1. jps 查看Java进程jps-l# 2. jstat 查看GC情况jstat-gcutil进程ID1000100# 3. jmap 生成堆转储jmap-dump:format=b,file=heap.hprof 进程ID# 4. MAT分析dump文件

5.4 实际调优案例

案例:某服务频繁Full GC

# 原始配置-Xms2g-Xmx2g-XX:+UseParallelGC# 现象# Full GC每分钟2-3次,每次停顿3-5秒# 分析jstat-gcutil进程ID100010# 发现Old区占用95%以上# 优化配置-Xms4g-Xmx4g-Xmn1g-XX:+UseG1GC-XX:MaxGCPauseMillis=200-XX:InitiatingHeapOccupancyPercent=50# 效果# Full GC降到每10分钟1次,停顿<1秒

六、CPU 100%排查

# 1. 找到CPU占用高的进程top# 2. 找到该进程中高CPU的线程top-Hp进程ID# 3. 将线程ID转为16进制printf"%x\n"线程ID# 4. 查看线程堆栈jstack 进程ID|grep16进制线程ID-A50

总结

模块核心知识点
内存模型堆/栈/方法区/程序计数器
垃圾回收可达性分析/引用类型/GC Roots
垃圾回收器Serial/ParNew/Parallel/CMS/G1/ZGC
调优参数-Xms/-Xmx/-Xmn/-XX:+UseG1GC
排查工具jps/jstat/jmap/jstack/MAT

http://www.jsqmd.com/news/700137/

相关文章:

  • 51单片机实战:从直流电机调速到步进电机精确定位
  • MogFace人脸检测工具效果实测:cv_resnet101_face-detection_cvpr22papermogface极端姿态识别能力
  • 网站建设不只是「做个页面」:潍坊企业技术选型的五个关键判断
  • UIEffect终极指南:3分钟为Unity UI添加专业级视觉效果
  • 从0x000000D1蓝屏到系统稳定:深入剖析iaStorA.sys故障的根源与修复路径
  • D2RML终极指南:如何5分钟实现暗黑破坏神2重制版高效多开
  • 惊群效应(Thundering Herd)深度解析
  • TiDB 实战项目:从需求分析到生产级代码完整记录
  • 水族用品推荐 - 观域传媒
  • 暗黑破坏神2存档编辑革命:告别繁琐,拥抱网页端自由定制
  • 前荣耀CEO赵明首秀,千里科技欲三年内跻身智驾行业头部,目标能否达成?
  • Go语言中间代理库MPS:构建灵活HTTP/HTTPS流量控制中间件
  • GetQzonehistory:三步搞定QQ空间说说完整备份,永久珍藏你的数字记忆
  • 重庆江津云澜栖避暑房二手房折价率回归分析:哪些特征影响保值?
  • 2026 年最新:Anthropic 注册政策变化及应对策略
  • 有封面图的
  • 【YOLOv5改进实战】Neck特征融合新思路:CAM模块在PANet不同层级的注入与性能调优
  • C++ 类型转换深度解析:static_cast、dynamic_cast、const_cast、reinterpret_cast
  • ​.NET 实战:Redis 缓存穿透、击穿与雪崩的原理剖析与解决方案
  • 企业级AI操作系统Casibase:统一管理多模型与智能体编排的RAG平台
  • 网络安全学习路线全图谱:从零基础到高阶专家
  • Python 哨兵值模式(Sentinel Value Pattern)深度解析
  • SecGPT-14B精彩案例分享:真实CTF题目自动解析+EXP构造逻辑生成过程
  • 手撕CUDA 13新特性:如何用Cooperative Groups重构AllReduce——分布式训练通信开销直降41%(含NCCL 2.18源码补丁)
  • Day08-MySQL
  • 10个实用技巧:用AnimateDiff插件轻松制作AI动画视频
  • AI Coding 选哪一家?2026 全面对比指南
  • uni-app 高阶实战:onLoad与getCurrentPages深度技巧
  • 5分钟精通Illustrator批量替换:ReplaceItems.jsx终极指南
  • 高波动行情,如何保证数据零丢失?