连载中 19/20

堆外内存:-Xmx 管不到的那部分

2026-09-20 · 8 阅读 · 0 评论 · 0 赞

进程内存全景

进程实际占用的内存(RSS)远不止堆:堆(-Xmx)+ 元空间(-XX:MaxMetaspaceSize)+ 每线程栈(-Xss × 线程数)+ 直接内存(-XX:MaxDirectMemorySize)+ JIT 编译缓存(Code Cache)+ GC 开销 + JVM 自身。容器里配额只按 -Xmx 算是经典事故——堆没满,容器先 OOM,OOM Killer 杀进程时连个 Java 异常都来不及打印。JDK 8u191+ 对容器有了感知(UseContainerSupport),但仍建议显式设置各块上限。

元空间:类装到哪里了

元空间装类元数据,位于本地内存。正常服务类数量固定,元空间平稳;动态生成类是变数——CGLIB 代理、反射 inflate、Groovy/JSP 编译、字节码增强框架,每个都往里塞类。泄漏信号:MAT 里同名类一堆(不同 ClassLoader 各一份)、jstat -gcutil 的 M 列只涨不跌。防法:MaxMetaspaceSize 设上限,超了宁可 OOM 也好过吃穿容器。

直接内存:NIO 的地盘

// 直接内存:绕过 JVM 堆,操作系统直接管理
ByteBuffer buf = ByteBuffer.allocateDirect(1024 * 1024);
// 为什么用它:网络 IO 时省一次"堆内存 → 内核缓冲区"的拷贝
// 代价:分配/释放慢(靠 Cleaner 专职线程回收,时机不可控)
// 上限:-XX:MaxDirectMemorySize(默认≈-Xmx)
//
// Netty 的池化堆外内存(PooledDirectByteBuf)是集大成者:
//   按 ByteBuf 引用计数管理,用完必须 release()
//   忘 release 的代价:堆外只涨不跌,最终 Direct buffer memory OOM
//   开启 -Dio.netty.leakDetection.level=PARANOID 能抓到泄漏点

排查工具:NMT 是主力

堆外问题 heap dump 无能为力,要用 Native Memory Tracking:启动加 -XX:NativeMemoryTracking=summary(detail 更细但 overhead 略高),运行时 jcmd PID VM.native_memory summary 看各区域占用,diff 前后快照看谁在涨。NMT 只统计 JVM 自己的账(堆、元空间、线程、Code Cache、GC),RSS 减去 NMT 总账的差额,多半就是 DirectBuffer 这类"自由发挥"的部分——对不上账时用 pmap 按地址段挨个认领。

一次 Netty 泄漏复盘

网关服务 RSS 每天涨 300M,heap dump 干干净净。NMT 显示 JVM 内部各区平稳——差额在堆外。开 Netty 泄漏检测 PARANOID 级,日志抓到 LEAK: ByteBuf.release() was not called,定位到一处异常分支提前 return 没释放 buffer。修复后 RSS 稳定。结论记两条:堆外问题先看 RSS 与 NMT 的差额;Netty 项目上线前把泄漏检测开成 SIMPLE 级做一次压测。下一篇收官,把二十篇串成一张地图。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#堆外内存#直接内存#元空间#NMT#Netty泄漏

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞