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

如何调试通过JNI被Java调用的DLL内存泄漏问题

JNI调用C++ DLL的内存泄漏调试方案

一、调整调试器中断规则,减少无关干扰

  • 在Visual Studio中打开异常设置(快捷键Ctrl+Alt+E),取消勾选Win32 Exceptions下非必要的异常类型,仅保留与内存问题强相关的选项(如内存访问违例)。
  • 调试会话启动后,右键点击调用栈里的java.exe或jvm.dll进程,选择符号加载设置,取消加载这些模块的符号,避免调试器在Java侧代码中触发中断。
  • 给JNI导出函数设置条件断点,仅在进入你的C++ DLL代码逻辑时暂停,跳过Java侧的执行流程。

二、适配场景的内存泄漏检测工具

  • Visual Studio Memory Profiler优化用法:启动调试时选择性能探查器(快捷键Alt+F2),仅勾选“内存使用”项启动会话。运行过程中手动触发DLL核心逻辑,多次抓取内存快照,对比快照间的增量,按模块名称筛选出你的DLL相关内存分配记录。
  • Deleaker定向跟踪:先启动Java进程,再用Deleaker附加到该进程。在工具设置中勾选“仅跟踪指定模块”,添加你的C++ DLL路径,让工具只记录该模块的内存分配与释放操作。
  • Dr. Memory:开源内存调试工具,支持Windows平台。启动工具并附加到Java进程,它会拦截所有内存操作,运行业务逻辑后生成泄漏报告,可筛选出你的DLL相关泄漏点。
  • Valgrind(Memcheck):若DLL可在WSL或Linux环境编译运行,用Valgrind的Memcheck工具跟踪Java进程加载.so库的内存操作,能精准定位未释放内存块的调用栈。

三、代码层面的辅助排查手段

  • 给C++ DLL封装自定义内存分配函数,重载new/delete或实现专属分配逻辑,分配时用CaptureStackBackTrace记录调用栈,释放时移除记录,程序退出时输出未释放内存块的调用栈信息。
  • 利用JNI生命周期钩子:在JNI_OnLoad和JNI_OnUnload中添加内存统计逻辑,记录DLL从加载到卸载的内存变化,缩小泄漏发生的阶段范围。
  • 规范JNI本地引用管理:确保所有通过NewLocalRef创建的本地引用,使用完后调用DeleteLocalRef释放,避免这类间接内存占用被误判为C++泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:22:40