JDK1.8中VM.native_memory的BOOTSTRAP内存持续增长原因求助
Spring Boot 2.7.9 服务被K8s杀死,BOOTSTRAP Internal内存持续增长的排查方向
可能的原因及排查手段
1. Bootstrap类加载器的类/资源泄漏
Bootstrap类加载器负责加载JVM核心类及Spring Boot框架级资源,若存在未释放的引用,会直接导致其关联的Internal内存持续增长:
- 自定义SPI实现、扩展点未正确关闭资源,导致类加载器持有长期引用
- 第三方依赖中的静态缓存无大小限制,持续累积对象或元数据
- 排查方式:导出堆快照
jmap -dump:format=b,file=heap.hprof <pid>,通过MAT/VisualVM分析BootstrapClassLoader的引用链,定位未释放的类实例或资源。
2. JVM Native Internal区域的资源未释放
NMT中type=Internal包含JVM内部元数据、锁对象、JNI句柄等,Bootstrap关联的该区域增长可能和以下情况有关:
- 频繁触发类加载(Bootstrap加载的类通常不会卸载,若存在重复加载逻辑会导致元数据累积)
- 第三方依赖或自定义JNI扩展未正确释放本地资源,导致句柄泄漏
- 排查方式:执行
jcmd <pid> VM.native_memory detail.diff对比不同时间点的内存变化,定位增长最快的子区域;结合jstack <pid>查看是否有持续运行的JNI调用线程。
3. Spring Boot 2.7.x版本已知问题
部分2.7.x版本存在类加载器相关的内存泄漏:
- 若使用Spring Cloud,Bootstrap上下文未正确关闭导致资源残留
- 自动配置模块中部分组件未释放资源(如配置加载器、监听器)
- 解决方向:升级到Spring Boot 2.7.x最新小版本(如2.7.18),查看官方Release Notes确认是否有对应修复补丁。
4. K8s资源限制与OOMKill的关联
K8s的内存限制会直接触发OOMKill,需确保JVM堆内存+Native内存总和不超过限制:
- 检查
resources.limits.memory配置是否合理,避免Native内存挤占堆空间 - 调整JVM参数:设置
-XX:MaxDirectMemorySize限制直接内存,适当调低-Xmx为Native内存预留空间
额外分析步骤
- 定期采集NMT快照,对比内存增长趋势,锁定关键增长区域
- 用依赖分析工具(如
mvn dependency:tree)排查重复依赖、过时依赖,排除第三方组件泄漏 - 开启Spring Boot的DEBUG日志,跟踪Bootstrap上下文的初始化与销毁流程,确认资源释放逻辑
内容的提问来源于stack exchange,提问作者pingzi
相关产品推荐
相关产品推荐

