You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何排查Java JNI调用C/C++代码引发的容器非JVM堆内存溢出问题

Native内存排查工具推荐(针对JNI调用C/C++场景)
  • AsyncProfiler:轻量级线上排查工具,性能损耗极低(通常低于5%),支持采样malloc/mmap的调用栈,直接生成火焰图展示C/C层内存分配占比。使用前需要给ECS容器开启SYS_PTRACE权限,执行命令./profiler.sh -d 60 -e malloc -f native_alloc_flamegraph.html <Java进程PID>,生成的火焰图可直接定位到内存占比最高的C/C函数,配合带符号表的编译产物即可对应到具体的类、结构体分配逻辑。
  • gperftools Heap Profiler:性能损耗远低于Valgrind,适合预发/灰度环境使用,可统计全量内存分配数据。使用时预加载tcmalloc动态库启动Java进程:LD_PRELOAD=/path/to/libtcmalloc.so HEAPPROFILE=./heap_output <Java启动命令>,程序运行过程中会按内存分配阈值生成快照,使用pprof --text /path/to/java heap_output.0001.heap即可查看内存分配Top列表,精准到具体的C/C++符号。
  • Valgrind Massif:适合线下复现场景的全量内存分析工具,可输出完整的内存分配生命周期栈。使用命令valgrind --tool=massif --massif-out-file=mem_result <Java启动命令>,流量复现后停止进程,执行ms_print mem_result即可查看内存分配的详细调用栈,可直接定位到具体的struct/class分配代码行。
容器环境排查注意事项
  • ECS任务定义中需开启SYS_ADMIN、SYS_PTRACE权限,关闭Docker默认的ptrace限制,否则工具无法attach到目标进程采集数据
  • C/C++动态库编译时需添加-g编译参数保留符号表,否则工具只能输出内存地址,无法对应到具体的类、结构体、函数名
  • JDK自带的jcmd <pid> VM.native_memory仅统计JVM自身申请的Native内存,不会统计JNI调用的C/C++代码中主动malloc/new申请的内存,因此无法用于该场景的问题定位

内容的提问来源于stack exchange,提问作者alext

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:24:05