JVM调优
JVM调优一般分两种情况考虑:
1、根据需求进行JVM的规划和预调优。
吞吐量、及时响应的需求不同使用不同的垃圾回收器。根据系统使用的技术,进行内存参数配置(如:netty,堆内存与对外内存1:1。其他可以设置2:1)。
2、优化正在运行中的jvm(慢,卡顿)
已运行JVM需要以下数据:
①、CPU,磁盘,内存的IO监控数据
②、JVM的监控数据
③、压测数据
可进行堆内存参数配置,选择不同的垃圾回收器,分带年龄配置,优化程序代码等手段优化。
场景:
①、导入导出。
②、最小启动内存配置。
③、程序代码优化,如增加池化处理,如异步线程池、数据库线程池、redis线程池等。
3、解决jvm运行中的各种问题,oom等。
调优JVM其实就是在理解JVM内存结构以及各种垃圾收集器前提下,结合自己的现有的业务来调整参数,使自己的应用能够正常稳定运行。
一般调优JVM我们认为会有几种指标可以参考:『吞吐量』、『停顿时间』和『垃圾回收频率』。
基于这些指标,我们就有可能需要调整:
- 内存区域大小以及相关策略
比如:整块堆内存占多少、新生代占多少、老年代占多少、Survivor占多少、晋升老年代的条件等等
比如:-Xmx:设置堆的最大值、-Xms:设置堆的初始值、-Xmn:表示年轻代的大小、-XX:SurvivorRatio:伊甸区和幸存区的比例等等
按经验来说:IO密集型的可以稍微把「年轻代」空间加大些,因为大多数对象都是在年轻代就会灭亡。内存计算密集型的可以稍微把「老年代」空间加大些,对象存活时间会更长些 - 垃圾回收器
选择合适的垃圾回收器,以及各个垃圾回收器的各种调优参数
比如:-XX:+UseG1GC:指定 JVM 使用的垃圾回收器为 G1、-XX:MaxGCPauseMillis:设置目标停顿时间、-XX:InitiatingHeapOccupancyPercent:当整个堆内存使用达到一定比例,全局并发标记阶段 就会被启动等等
没错,这些都是因地制宜,具体问题具体分析(前提是得懂JVM的各种基础知识,基础知识都不懂,谈何调优)
一般我们是「遇到问题」之后才进行调优的,而遇到问题后需要利用各种的「工具」进行排查
- 通过jps命令查看Java进程「基础」信息(进程号、主类)。这个命令很常用的就是用来看当前服务器有多少Java进程在运行,它们的进程号和加载主类是啥
- top命令查看,cpu状态信息,内存使用信息,进程相关信息。
- cat工具查看CPU,内存,垃圾回收频率。判断是否有问题。
- 还有比较热门的Arthas(阿里开源的诊断工具),涵盖了上面很多命令的功能且自带图形化界面。这也是我这边常用的排查和分析工具
java 内存泄漏排查定位
1、首先 top查看 CPU 内存使用情况,发现过高。 垃圾回收频率过快,fullGC 频率过高
2、使用jmap命令导出head dump文件
3、使用JDK自带的VisualVM工具,查看dump文件,内存泄漏会有提示。
可以使用MAT 工具查看,同样会提醒内存泄漏相关代码 会列出内存占用列表,哪个类占内存用最多一目了然。
进程消耗的cpu高问题排查
1、top查找出哪个进程消耗的cpu高
top
2、根据进程号查找线程
top -H -p 5918
3、线程号转换16进制,jstack命令打印相关日志
// -A 100表示查找到所在行的后100行。5919用计算器转换为16进制171f,注意字母是小写。
jstack 5918 | grep -A 100 171f
一键查找问题脚本
show-busy-java-threads项目
当系统订单量达到 100 万级时,通常意味着应用的内存压力较大(如订单数据缓存、并发处理中的对象创建等),GC(垃圾回收)配置需要兼顾吞吐量(减少 GC 总耗时)和延迟(避免长时间 STW 导致订单处理超时)。以下是针对 100 万级订单场景的 GC 参数配置思路和核心参数建议,以主流的 JVM(HotSpot)为例:
一、核心目标:平衡吞吐量与延迟
100 万级订单系统通常具备高并发(短时间内大量订单创建 / 处理)、内存对象生命周期差异大(临时订单对象、缓存的长期订单数据)的特点,因此 GC 配置需实现:
减少频繁 GC(尤其是 Young GC)对实时订单处理的干扰;
避免 Full GC 过长导致的订单超时(如支付回调、库存扣减等关键步骤);
确保内存利用高效,避免 OOM(内存溢出)影响系统稳定性。
二、GC 收集器选择
优先推荐G1(Garbage-First),适合大内存(通常 16GB 以上)、需要平衡吞吐量和延迟的场景,100 万级订单系统的内存配置建议至少 16GB(根据实际订单数据量可增至 32GB),G1 的优势在于:
支持动态区域划分,可针对订单处理中大量短期对象(Young 区)和长期缓存对象(Old 区)分别优化;
可设置最大 STW(Stop-The-World)时间目标,避免订单处理超时;
相比 CMS,对大内存的处理效率更高,减少 Full GC 风险。
若系统对延迟要求极高(如毫秒级响应),且内存规模超大(64GB 以上),可考虑ZGC或Shenandoah(需 JDK11+),但配置复杂度更高,需结合实际压测验证。
三、核心参数配置(基于 G1 收集器)
- 内存基础配置
java
运行
-Xms16g -Xmx16g // 堆内存初始值=最大值(避免动态扩容的性能损耗)
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g // 元空间(类信息),避免频繁扩容
-XX:ReservedCodeCacheSize=256m // 代码缓存(JIT编译的代码)
堆内存大小:100 万级订单若涉及缓存(如本地缓存订单信息),建议 16GB 起,根据压测中内存占用调整(避免频繁 Full GC);
元空间:订单系统可能依赖大量框架类(如 Spring、MyBatis),512m~1g 足够,避免默认值过小导致频繁扩容。 - G1 核心参数
java
运行
-XX:+UseG1GC // 启用G1收集器
-XX:MaxGCPauseMillis=200 // 目标最大STW时间(毫秒),根据订单超时阈值设置(如200ms)
-XX:G1HeapRegionSize=32m // 每个Region大小(1M~32M,2的幂),大对象多可设大(如32m)
-XX:G1NewSizePercent=5 // 年轻代最小占比(默认5%)
-XX:G1MaxNewSizePercent=60 // 年轻代最大占比(默认60%),高并发场景可提高(如60%)
-XX:G1ReservePercent=15 // 预留内存占比(默认10%),防止晋升失败(OOM),订单峰值期建议15%
-XX:ParallelGCThreads=8 // GC并行线程数(建议=CPU核心数,避免过多线程竞争资源)
-XX:ConcGCThreads=2 // 并发标记线程数(默认=ParallelGCThreads/4)
MaxGCPauseMillis:关键参数,需根据订单处理的超时时间设置(如订单支付允许的最大延迟是 500ms,则设为 200ms,留缓冲);
G1HeapRegionSize:订单处理中若有大对象(如订单详情 JSON、批量订单列表),建议设为 32m(避免大对象跨多个 Region 导致的回收效率低);
G1ReservePercent:订单峰值时(如秒杀场景),大量对象可能从年轻代晋升到老年代,预留 15% 内存可减少 “晋升失败” 导致的 Full GC。 - 避免 Full GC 的参数
java
运行
-XX:InitiatingHeapOccupancyPercent=45 // 触发并发标记的堆占用阈值(默认45%),订单系统可适当降低(如45%),提前启动回收
-XX:G1MixedGCLiveThresholdPercent=85 // 混合回收时,Old区Region的存活对象阈值(默认85%),低于此值才会被回收,可降低至80%提高回收效率
-XX:G1MixedGCCountTarget=8 // 混合回收的Region数量目标(默认8),可增加至16,加快Old区回收
订单系统的 Old 区可能缓存大量历史订单数据,提前触发并发标记(降低InitiatingHeapOccupancyPercent)可避免堆内存占满后触发 Full GC。 - 日志与监控参数
java
运行
-XX:+PrintGCDetails -XX:+PrintGCDateStamps // 打印GC详细日志(时间、耗时、内存变化)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heapdump.hprof // OOM时自动dump堆快照,用于分析内存泄漏(如订单对象未释放)
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100m // GC日志轮转,避免单个文件过大
100 万级订单系统必须开启 GC 日志和 OOM 快照,用于排查内存泄漏(如订单缓存未及时过期)、GC 频繁等问题。
四、特殊场景优化
秒杀 / 峰值订单场景:
临时调大年轻代比例(G1MaxNewSizePercent=70%),减少短期订单对象晋升到老年代;
提前预热 JVM(加载类、初始化缓存),避免峰值期因类加载导致的 GC 波动。
订单数据缓存场景:
若使用本地缓存(如 Caffeine)存储热点订单,设置合理的过期时间,避免缓存对象长期占用 Old 区;
监控 Old 区增长率,若持续上涨(如缓存未过期),需调整缓存策略或增大堆内存。
批量处理订单(如定时任务):
批量处理时避免一次性创建 100 万订单对象,分批次处理(如每批 1 万),减少年轻代压力;
批量任务单独配置 JVM 参数(如更大的年轻代),避免影响实时订单处理。
五、验证与调优方法
压测验证:用 JMeter 模拟 100 万级订单并发,监控 GC 指标(Young GC 频率、Full GC 次数、STW 时长);
指标阈值:
Young GC:频率≤1 次 / 秒,单次耗时≤50ms;
Full GC:理想状态下 0 次,若不可避免,单次耗时≤1 秒;
堆内存利用率:峰值不超过 80%(预留缓冲)。
动态调整:根据压测结果微调参数(如MaxGCPauseMillis、G1HeapRegionSize),优先解决 “频繁 Full GC” 或 “STW 超时” 问题。
总结
100 万级订单系统的 GC 配置核心是 “用 G1 收集器,保证足够堆内存,控制 STW 时间,避免 Full GC”,具体参数需结合业务场景(实时处理 / 批量处理)、内存占用特征(临时对象 / 缓存对象占比)通过压测优化。关键是做好 GC 监控,及时发现内存泄漏或回收效率问题,避免影响订单流程稳定性。
如果需要针对具体业务场景(如电商订单、支付订单)的更细化配置,可以补充说明,我会进一步调整建议。

浙公网安备 33010602011771号