C 编译器应该立即释放 "further unused" 内存吗?
Should C compilers immediately free "further unused" memories?
上下文:在编译某些 C 代码时,编译器可能会显示高 RAM 消耗。初步调查表明(至少某些)C 编译器不会立即释放“进一步未使用”的内存:尽管不再使用此类(先前分配的)内存,但它们仍保留在 RAM 中。 C 编译器继续处理 C 代码,在 RAM 中分配更多内存,直到达到 OOM(内存不足)。
核心问题:C 编译器是否应该立即释放“更多未使用”的内存?
理由:
- 高效的 RAM 利用率:不再需要 mem_X => 免费 mem_X 让其他进程(本身包括)使用 mem_X。
- 能够编译“RAM 要求高”的 C 代码。
UPD20210825。我对一些 C 编译器进行了内存分析,发现它在 RAM 中保存了“C 预处理器数据”,特别是:
宏table(宏的内存池);
扫描仪令牌对象(令牌和列表的内存池)。
在中端的某个点 X(在 IR 构建之后)这些对象似乎不再需要,因此可以被释放。 (但是,现在这些对象一直保存在 RAM 中,直到点 X+1。)在“预处理器繁重”的 C 程序中可以看到好处。示例:使用通过 C 预处理器实现的“临时多态性”的“预处理器繁重”C 程序(通过使用一组宏,它逐步实现所有需要的“机器”以支持任意(和支持的)单独集合的通用接口指定类型)。 “多态”条目的数量是~50k * 12 = ~600k(是的,它什么也没说)。结果:
- 修复前:X C 编译器在 RAM 中保留了 ~1.5GB 未使用的“C 预处理器数据”;
- 修复后:在点 X C 编译器从 RAM 中释放 ~1.5GB 未使用的“C 预处理器数据”,因此,让 OS 进程(本身包括)使用这些 ~1.5GB。
我不知道你的分析是从哪里来的。保留了抽象语法树等大部分内容,因为它用于所有不同的过程。
可能是某些编译器,尤其是简单的编译器不释放某些东西,因为 C 编译器认为它不是必需的。这是一次性编译单元操作,然后过程结束。
当然,如果您构建像 tinycc 这样的编译器库,您是否需要释放所有内容,但即使这样也可能发生在编译结束时的最终自定义堆清除范围内 运行。
我还没有发现这在现实世界中是个问题。但我不做嵌入式的东西,因为缺乏资源可能会让人担心。
allocating more memories in the RAM, until it reaches OOM (out of
memory).
我使用的 None 个编译器 运行 内存不足。请举例说明这种行为。
如果您是 Arduino 用户并且考虑到代码无法放入内存 - 这不是编译器的问题,而是程序员的问题。
上下文:在编译某些 C 代码时,编译器可能会显示高 RAM 消耗。初步调查表明(至少某些)C 编译器不会立即释放“进一步未使用”的内存:尽管不再使用此类(先前分配的)内存,但它们仍保留在 RAM 中。 C 编译器继续处理 C 代码,在 RAM 中分配更多内存,直到达到 OOM(内存不足)。
核心问题:C 编译器是否应该立即释放“更多未使用”的内存?
理由:
- 高效的 RAM 利用率:不再需要 mem_X => 免费 mem_X 让其他进程(本身包括)使用 mem_X。
- 能够编译“RAM 要求高”的 C 代码。
UPD20210825。我对一些 C 编译器进行了内存分析,发现它在 RAM 中保存了“C 预处理器数据”,特别是:
宏table(宏的内存池);
扫描仪令牌对象(令牌和列表的内存池)。
在中端的某个点 X(在 IR 构建之后)这些对象似乎不再需要,因此可以被释放。 (但是,现在这些对象一直保存在 RAM 中,直到点 X+1。)在“预处理器繁重”的 C 程序中可以看到好处。示例:使用通过 C 预处理器实现的“临时多态性”的“预处理器繁重”C 程序(通过使用一组宏,它逐步实现所有需要的“机器”以支持任意(和支持的)单独集合的通用接口指定类型)。 “多态”条目的数量是~50k * 12 = ~600k(是的,它什么也没说)。结果:
- 修复前:X C 编译器在 RAM 中保留了 ~1.5GB 未使用的“C 预处理器数据”;
- 修复后:在点 X C 编译器从 RAM 中释放 ~1.5GB 未使用的“C 预处理器数据”,因此,让 OS 进程(本身包括)使用这些 ~1.5GB。
我不知道你的分析是从哪里来的。保留了抽象语法树等大部分内容,因为它用于所有不同的过程。
可能是某些编译器,尤其是简单的编译器不释放某些东西,因为 C 编译器认为它不是必需的。这是一次性编译单元操作,然后过程结束。
当然,如果您构建像 tinycc 这样的编译器库,您是否需要释放所有内容,但即使这样也可能发生在编译结束时的最终自定义堆清除范围内 运行。
我还没有发现这在现实世界中是个问题。但我不做嵌入式的东西,因为缺乏资源可能会让人担心。
我使用的allocating more memories in the RAM, until it reaches OOM (out of memory).
None 个编译器 运行 内存不足。请举例说明这种行为。
如果您是 Arduino 用户并且考虑到代码无法放入内存 - 这不是编译器的问题,而是程序员的问题。