CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页实践文章揭开Java容器‘消失的内存’之谜:云监控2.0 SysOM诊断实践

揭开Java容器‘消失的内存’之谜:云监控2.0 SysOM诊断实践

#云原生#Kubernetes#容器#监控#追踪#Java

agenticOps | 2026-05-23

背景

在前一篇文章《一次内存诊断,让资源利用率提升40%:揭秘隐式内存治理》[1]中,我们系统性地剖析了云原生环境中隐性内存开销的诊断方法,通过SysOM系统诊断实现了对节点/Pod级由文件缓存、共享内存等系统级内存资源异常消耗的精准定位。

然而,部分场景下内存异常仍可能源于应用进程本身的内存申请,但是对于应用内存泄漏问题,尽管是应用的开发者,也需要投入大量的精力去利用对应语言的内存分析工具去找出根因;以Java应用为例,当传统线下IDC集群中的Java应用完成云原生架构转型后,伴随容器化封装与资源配额管控的实施,用户普遍反馈Java应用Pod出现持续性内存超限及Kubernetes OOMKilled事件。这一系列现象主要集中在三个关键矛盾点:

  1. 容器内存监控与JVM堆内存的显著差异
    Pod内存占用常超出JVM堆内存(含堆外内存)数倍,形成"消失的内存"谜团
  2. 容器化改造后的OS兼容性问题
    同一业务系统在切换OS或容器化后,出现内存占用模式突变
  3. 工具链覆盖盲区
    传统Java内存分析工具无法覆盖JNI内存、LIBC内存等非JVM内存区域

为此,云监控2.0[2]中的SysOM系统诊断对应用内存进一步深挖,结合应用和操作系统的角度实现对主机、容器运行时及具体的Java应用进程进行内存占用拆解,快速有效地识别出Java内存占用的元凶

Java内存全景分析

为了找出消失的内存,我们首先要了解Java进程的主要内存组成以及现有工具和监控主要覆盖的部分;如下图所示可分为:

JVM内存

    • 堆内存:可通过-Xms/-Xmx参数控制,内存大小可通过memorymxbean等获取。
    • 堆外内存:包括元空间、压缩类空间、代码缓冲区、直接缓冲、线程栈等内存组成;它们分别可以通过-XX:MaxMetaspaceSize(元空间)、-XX:CompressedClassSpaceSize (压缩类空间)、 -XX:ReservedCodeCacheSize( 代码缓冲区)、-XX:MaxDirectMemorySize (直接缓冲)、-Xss(线程栈)参数限制。

非JVM内存:

    • JNI本地内存:即通过本地方法接口调用C、C++代码(原生库),并在这部分代码中调用C库(malloc)或系统调用(brk、mmap)直接分配的内存。

Java常见“内存泄漏”

JNI内存泄漏

经过上一章中对Java内内存全景的分析,其实已经可以揭开第一个容易造成内存黑洞的隐藏Boss-JNI内存,因为这部分内存暂时没有工具可以获取其占用大小。

通常来说,编写相关业务代码的同学会认为代码中没有使用本地方法直接调用C库,所以不会存在这些问题,但是代码中引用的各种包却有可能会使用到JNI内存,比如说经典的使用ZLIB 压缩库不当导致的JNI泄漏问题[3]

LIBC内存管理特性

JVM向OS申请内存的中间,还存在着一层中间层-C库,JVM调用malloc、free申请/释放内存的过程中其实还要经过这一个二道贩子;以gibc中默认的内存分配器ptmalloc为例glibc的ptmalloc内存分配器存在以下特征:

  • Arena机制:每个线程维护64M Arena,多线程场景下易产生内存碎片
  • Top Chunk管理:内存空洞导致无法及时归还OS
  • Bins缓存策略:JVM释放的内存暂存于bins中,造成统计偏差[4-5]

Linux透明大页(THP)影响

在OS层,Linux中的透明大页(Transparent Huge Page)机制也是造成JVM内存和实际内存差异的一大元凶。简单来说,THP机制就是OS会将4kb页变成2M的大页,从而减少TLB miss和缺页中断,提升应用性能,但是也带来了一些内存浪费。如应用申请了一段2M的虚拟内存,但实际只用了里面的4kb,但是由于THP机制,OS已经分配了一个2M的页了[6];

SysOM Java内存诊断实践:

下面将以汽车行业客户在从线下idc集群迁移至云上ACK集群时遇到的由于JNI内存泄漏导致Pod频繁OOM为例,介绍如何通过云监控2.0的SysOM系统诊断来一步步找出Java内存占用的元凶

诊断使用限制:

  • 目前仅支持openJDK 1.8以上版本
  • 使用JNI内存Profiling功能需要至操作系统控制台先对实例进行纳管[3],有一定的资源和性能开销(内存占用根据符号大小最高达300MB)

C2 compiler JIT 内存膨胀案例

案例背景

某汽车客户在ACK集群迁移过程中,多个Java服务Pod出现偶发性OOM。特征表现为:

  • Pod内存接近限制时触发OOM
  • JVM监控显示内存正常
  • 无明显请求异常或流量波动
排查过程:
  • 尝试在内存高水位时对Pod发起内存全景分析。
  • 我们可以了解到当Pod中容器内存使用已经接近limit,从诊断结论和容器内存占用分析中,我们可以看到容器内存主要是由于Java进程内存占用导致

对Java进程发起内存分析,查看诊断报告。报告展示了Java进程所在Pod和容器的rss和WorkingSet(工作集)内存信息、进程Pid、JVM内存使用量(即JVM视角的内存使用量)、Java进程内存使用量(进程实际占用内存),进程匿名用量以及进程文件内存用量。

通过诊断结论和Java内存占用饼图我们可以发现,进程实际内存占用比JVM监控显示的内存占用大570M,全都由JNI内存所贡献[4]。

开启JNI(Java Native Interface)内存分配profiling,报告列出当前Java进程JNI内存分配调用火焰图,火焰图中为所有分配JNI内存的调用路径。(说明:由于是采样采集,火焰图中的内存大小不代表实际分配大小)。

  • 从内存分配火焰图中,我们可以看到主要的内存申请为C2 compiler正在进行代码JIT预热;
  • 但是由于诊断的过程中没有发现pod有内存突增;所以我们进一步借助可以常态化运行的Java CPU热点追踪功能[5]尝试抓取内存升高时的进程热点,并通过热点对比[6]尝试对内存正常时的热点进行对比。
  • 通过热点栈和热点分析对比,发现内存突增时间点的cpu栈也是c2 compiler的JIT栈,且c2 compiler热点前有部分业务流量突增,且业务代码使用了大量反射操作(反射操作会导致c2 compiler进行新的预热)。
结论和解决方案:

C2 compiler JIT过程申请JNI内存,且由于glibc内存空洞等原因导致申请内存放大且延时释放。

  1. 调整C2 compiler参数,让其编译策略更保守,可以尝试调整相关参数,观察内存消耗变化。
  2. 调整glibc环境变量MALLOC_TRIM_THRESHOLD_,让glibc及时将内存释放回操作系统。

总结

通过系统化的内存诊断方法,我们得以穿透JVM黑盒,揭示JNI、LIBC及OS层面的内存管理特性。阿里云操作系统控制台的内存全景分析功能,为容器化Java应用提供了从进程级到系统级的立体化诊断能力,帮助开发者精准定位内存异常根源,有效避免OOM事件的发生。

相关链接

【1】《一次内存诊断,让资源利用率提升 40%:揭秘隐式内存治理》

https://developer.aliyun.com/article/1690267

【2】云监控-ECS洞察-SysOM系统诊断

https://cmsnext.console.aliyun.com/next/region/cn-shanghai/workspace/default-cms-1808078950770264-cn-shanghai/app/host/host-sysom

【3】操作系统控制台实例纳管

https://help.aliyun.com/zh/alinux/user-guide/system-management?spm=a2c4g.11186623.help-menu-2632541.d_2_0_4.14ef243dMTjYF1&scm=20140722.H_2851198._.OR_help-T_cn~zh-V_1#7895eb3dedfty

【4】操作系统控制台Java内存诊断

https://help.aliyun.com/zh/alinux/user-guide/java-memory-diagnostics?spm=a2c4g.11186623.help-menu-2632541.d_2_0_1_0_0_2.2fd8243d1slu08&scm=20140722.H_2979954._.OR_help-T_cn~zh-V_1

【5】操作系统控制台热点追踪

https://help.aliyun.com/zh/alinux/user-guide/process-hotspot-tracking

【6】操作系统控制台热点对比分析

https://help.aliyun.com/zh/alinux/user-guide/hot-spot-comparative-analysis

文章大纲

推荐文章

超过 2000+ 位开发者正在阅读

给 OpenClaw 加上企业级 Memory

给 OpenClaw 加上企业级 Memory

4646 阅读

阿里云 STAROps 全域智能运维平台发布!

阿里云 STAROps 全域智能运维平台发布!

3453 阅读

阿里云正式发布 RCA Benchmark

阿里云正式发布 RCA Benchmark

2716 阅读

推荐视频

UModel 最佳实践 Vol.1 UModel 数据建模全景解读

UModel 最佳实践 Vol.1 UModel 数据建模全景解读

3854 观看50:35
云监控2.0全景:可观测范式升级与智能运维蓝图

云监控2.0全景:可观测范式升级与智能运维蓝图

2532 观看41:06

推荐工具

精选可观测领域开发者工具

云监

云监控 2.0 沙箱体验

7483 使用

免费

免费网络拨测工具

2746 使用