标签:#MyBatis #性能调优 #JVM优化 #高并发
上个月,我们线上系统频繁报警。JVM 堆内存一路飙升,Full GC 一次接一次。CPU 打满、接口延迟、线程阻塞……整套系统几乎被拖垮。
我们以为是内存泄漏,结果排查下来,罪魁祸首竟然是 MyBatis 的默认配置。
我只改了几行参数, JVM 占用下降 35% GC 次数减少 75% 平均响应时间提升 36%
今天这篇文章,带你完整复盘这次调优全过程。
为什么 JVM 会被 MyBatis“吃爆”很多人不知道,MyBatis 的默认配置非常“温柔”,对开发友好,但对生产高并发场景却极度危险。
配置项
默认行为
问题
缓存范围
session
占用内存,不释放
懒加载
激进触发
加载无用对象,触发多次SQL
Fetch Size
无限制
一次查上万行,瞬间爆堆
Timeout
无限等待
慢 SQL 阻塞线程池
这些默认配置在测试时毫无问题,但一旦进入生产环境、并发上来——就成了性能“黑洞”。
优化目标:轻、快、省✅ 轻:减小单次查询内存占用✅ 快:控制 SQL 响应时间✅ 省:减少缓存冗余和资源占用
⚙️ 生产级 MyBatis 核心配置mybatis: configuration: default-statement-timeout: 30 # 限制SQL执行时间 default-fetch-size: 500 # 分批游标读取 aggressive-lazy-loading: false # 禁止激进懒加载 lazy-loading-enabled: true # 仅在使用时加载 multiple-result-sets-enabled: true # 支持多结果集 use-column-label: true # 使用列标签 cache-enabled: true # 开启二级缓存 call-setters-on-nulls: true # null值也调用setter local-cache-scope: statement # 缓存仅限当前语句 关键参数详解(建议收藏) 1️⃣ default-statement-timeout作用: 限制 SQL 最长执行时间(30 秒)问题: 慢 SQL 占用连接,导致线程堆积优化效果: 数据库阻塞率下降 30%
2️⃣ default-fetch-size作用: 控制单次从数据库取的记录数问题: 一次性查太多数据,JVM 瞬间分配大对象优化效果: 堆内存占用降低 35%
3️⃣ lazy-loading-enabled+ aggressive-lazy-loading作用: 控制懒加载行为优化策略: 开启懒加载,但禁止激进模式效果: 避免 N+1 查询 + 减少无效对象加载
4️⃣ local-cache-scope作用: 限定缓存作用范围优化策略: 从 session 改为 statement,执行完即释放效果: 内存更稳定,线程安全
5️⃣ cache-enabled作用: 启用二级缓存,减少重复查询效果: 热点数据响应加快 30%,数据库压力显著下降
实测效果对比指标项
优化前
优化后
改善幅度
JVM 堆内存
6.5 GB
4.2 GB
35%
Full GC 次数
每小时 12 次
每小时 3 次
75%
平均响应时间
380ms
240ms
⚡ +36%
数据库连接占用
高峰 95%
高峰 65%
✅ 稳定运行
⚙️ 配合连接池一起使用更稳仅优化 MyBatis 还不够,推荐搭配 HikariCP 参数共同优化:
spring: datasource: hikari: maximum-pool-size: 50 minimum-idle: 10 connection-timeout: 30000 max-lifetime: 1800000同时要注意:
优化 SQL 索引与分页 使用 LIMIT 控制结果集️ 监控慢 SQL,防止拖垮连接池 写在最后:性能不是调出来的,是设计出来的这次事故让我更深刻地意识到:
⚡ “配置不是细节,在高并发场景,它就是生死线。”
很多系统崩溃并不是因为代码写得烂,而是因为默认配置太天真。
别让默认参数决定你的系统命运。只需改几行配置,你的 JVM 就能重新呼吸。
欢迎留言,聊聊你踩过的 MyBatis 坑
转载请注明来自海坡下载,本文标题:《mybatis优化(JVM 内存爆炸我只改了 5 行 MyBatis 配置)》
京公网安备11000000000001号
京ICP备11000001号
还没有评论,来说两句吧...