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

如何在程序退出时释放LLVM分配的全部内存?

解决LLVM-C程序中Valgrind检测到的"still reachable"内存残留

这个问题我之前折腾过好几次——虽然still reachable的内存通常不会造成实际泄漏(程序退出时操作系统会直接回收),但如果想让Valgrind的报告彻底清零,还是有办法的!

1. 显式管理LLVM Context是关键

你现在用的是LLVM的默认全局Context,这个Context的内存是在第一次调用LLVM API时初始化的,而且LLVM默认不会主动销毁它(毕竟程序马上要退出了,没必要花时间释放),这就是Valgrind标记的残留来源之一。

试试改成显式创建并销毁Context的写法:

#include <stdio.h>
#include <llvm-c/Core.h>
int main() {
    size_t length;
    // 手动创建专属Context
    LLVMContextRef context = LLVMContextCreate();
    // 在这个Context里创建Module
    LLVMModuleRef module = LLVMModuleCreateWithNameInContext("llvm.hello", context);
    
    printf("Module name: %s\n", LLVMGetModuleIdentifier(module, &length));
    
    // 销毁顺序要注意:先销毁Module,再销毁Context
    LLVMDisposeModule(module);
    LLVMContextDispose(context);
    
    LLVMShutDown();
    return 0;
}

这样可以把默认Context带来的残留内存释放掉。

2. 确认LLVMShutDown()的调用时机

一定要保证LLVMShutDown()在所有LLVM对象(Module、Context、Function这些)都销毁之后再调用,而且只能调用一次。它负责清理LLVM内部的全局初始化状态,比如组件注册表、共享内存池这些。

3. 用LLVM官方抑制文件快速"消警"(可选)

如果你只是不想看到Valgrind的这些报告,不想改代码的话,可以用LLVM官方提供的Valgrind抑制文件。在LLVM源码目录的utils/valgrind/llvm.supp里就能找到,运行Valgrind时加上参数:

valgrind --leak-check=full --suppressions=llvm.supp out/hello_llvm

这样Valgrind就会自动忽略LLVM内部已知的、不会造成问题的内存残留。

为啥会有这些残留?

LLVM内部有不少全局静态结构,比如组件注册表、默认内存池,这些都是在第一次调用API时初始化的。LLVM的设计思路是:反正程序退出时操作系统会回收这些内存,主动释放反而增加不必要的开销,所以就没做这部分的清理——这也是很多底层库的常见做法。

按上面的方法调整后,你应该能看到Valgrind的still reachable残留降到零啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:32:26