C编译器是否应当立即释放后续不再使用的内存空间?
C编译器内存释放问题分析
背景
编译C代码时部分编译器会出现RAM占用过高的问题,初步调研显示,至少部分C编译器不会立即释放后续不再使用的内存:即便此前分配的内存已无使用需求,仍会被保留在RAM中。C编译器持续处理代码、分配更多内存,直至触发OOM(内存不足)。
核心问题
C编译器是否应当立即释放后续不再使用的内存?
支持立即释放的理由
- 高效RAM利用:不再需要mem_X时就释放mem_X,可供包括编译器自身在内的其他进程使用。
- 支持编译高内存需求的C代码。
2021年8月25日实测更新
笔者对部分C编译器做了内存剖析,发现其会在RAM中保留C预处理器数据,具体包括:
- 宏表(macro table,宏的内存池
memory pool) - 扫描器令牌对象(scanner token objects,令牌和列表的内存池
memory pool)
在中端(middle-end)的某个节点X(IR构建完成后),上述对象已无使用需求,本可被释放,但当前这些对象会被保留在RAM中直到X+1节点。
该优化对*预处理器密集型(preprocessor-heavy)*C程序收益明显,示例:通过C预处理器实现ad hoc polymorphism的预处理器密集型C程序(通过一组宏逐步实现所需全部机制,为任意支持的单独指定类型提供通用接口),其“多态”条目数量约为50k * 12 = ~600k,测试结果如下:
- 修复前:在节点X处C编译器在RAM中保留了约1.5GB未使用的C预处理器数据
- 修复后:在节点X处C编译器释放了这部分约1.5GB的未使用C预处理器数据,可供包括编译器自身在内的操作系统进程使用
内容的提问来源于stack exchange,提问作者pmor
相关产品推荐
相关产品推荐

