C 编译器应该立即释放"further unused"内存吗?



上下文:在编译一些C代码时,编译器可能会显示高内存消耗。初步调查显示(至少有些)C编译器不会立即释放"进一步未使用的"代码。内存:尽管这些(先前分配的)内存不再使用,但它们仍然保存在RAM中。C编译器继续处理C代码,在RAM中分配更多内存,直到达到OOM(内存不足)。

核心问题:C编译器是否应该立即释放"进一步未使用的";记忆?

原理:

  1. 高效内存利用率:不再需要mem_X =>释放mem_X让其他进程(包括自身)使用mem_X。
  2. 能够编译"RAM需求";C代码。

UPD20210825。我对一些C编译器进行了内存分析,发现它在RAM中保留了"C预处理器数据",特别是:

  • 宏表(宏内存池);

  • 扫描令牌对象(用于令牌和列表的内存池)。

在中间端的某个点X(在构建IR之后),这些对象似乎不再需要,因此可以释放。(然而,现在这些对象被保存在RAM中,直到点X+1。)在"预处理量很大"的情况下可以看到这种好处。C程序。例如:"preprocessor-heavy"使用"自适应多态性"的C程序;通过C预处理器实现(通过使用一组宏),它逐步实现所有需要的"机器"。为任意(且受支持的)单独指定类型集合提供公共接口。"多态"的数量条目数是~50k * 12 = ~600k(是的,它什么也没说)。结果:

  • 修复前:在X点C编译器在RAM中保留了1.5GB未使用的"C预处理器数据";
  • 修复后:在X点C编译器从RAM中释放了1.5GB未使用的"C预处理器数据",因此,让操作系统进程(包括自身)使用这1.5GB。

我不知道你的分析是从哪里来的。像抽象语法树这样的大部分部分被保留,因为它在所有不同的过程中使用。

可能是一些,特别是简单的编译器不释放东西,因为它被认为不是C编译器所必需的。这是一次编译单元操作,然后进程结束。

当然,如果您构建像tinycc这样的编译器库,您需要释放所有内容,但即使这样,也可能在编译运行结束时的最终自定义堆清除中发生。

我在现实世界中从未见过这是一个问题。但我不做嵌入式的东西,因为缺乏资源会让人担心。

在RAM中分配更多内存,直到达到OOM (out of)内存)。

我使用的编译器都没有耗尽内存。请举一个这样的例子。

如果你是一个Arduino用户,并且考虑不适合内存的代码-这不是编译器的问题,只有程序员。

最新更新