为什么我们不应该在嵌入式系统中拥有不同大小的动态分配内存

Hao*_*hen 3 embedded memory-management dynamic-memory-allocation static-memory-allocation

我在嵌入式系统中听说过,我们应该使用一些预先分配的固定大小的内存块(比如好友内存系统?).有人能给我一个详细的解释原因吗?谢谢,

Uli*_*ler 11

在嵌入式系统中,内存非常有限.因此,如果你偶尔会丢失一个字节的内存(因为你分配了它,但你没有释放它),这将很快耗尽系统内存(1 GB的内存,泄漏率为1 /小时将占用它时间.如果你有4kB内存,不会那么久)

本质上,避免动态内存的行为是避免程序中的错误的影响.由于静态内存分配是完全确定的(而动态内存分配不是),通过仅使用静态内存分配,可以抵消此类错误.其中一个重要因素是嵌入式系统通常用于安全关键应用程序.几个小时的停机可能会花费数百万美元,或者可能发生事故.

此外,取决于动态内存分配器,不确定性也可能需要不确定的时间,这可能导致更多的错误,尤其是在依赖紧张时序的系统中(感谢Clifford提到这一点).这种类型的错误通常难以测试和重现,因为它依赖于非常具体的执行路径.

此外,嵌入式系统通常没有MMU,因此没有内存保护.如果内存不足并且处理该条件的代码不起作用,最终可能会执行任何内存作为指令(可能会发生错误!但这种情况只与动态内存分配间接相关).

正如郝申所说,碎片化也是一种危险.它是否可能发生取决于您的确切用例,但在嵌入式系统中,由于碎片,很容易丢失50%的RAM.如果分配的块总是具有完全相同的大小,则只能避免碎片.

表演也起到了一定的作用(取决于用例 - 感谢郝申).静态分配的内存由编译器分配,而malloc()类似的需要在设备上运行,因此消耗CPU时间(和功率).

许多嵌入式操作系统(例如ChibiOS)支持某种动态内存分配器.但使用它只会增加发生意外问题的可能性.

请注意,通常使用较小的静态分配内存池来规避这些参数.这不是一个真正的解决方案,因为在这些池中仍然可能耗尽内存,但它只会影响系统的一小部分.

正如Stephano Sanfilippo所指出的,某些系统甚至没有足够的资源来支持动态内存分配.

注意:大多数编码标准,包括JPL编码标准DO-178B(用于关键航空电子设备代码 - 感谢[Stephano Sanfilippo])(/sf/users/164120911/)禁止使用malloc.

我还假设MISRA C标准禁止malloc()因为这个论坛帖子 - 但是我无法访问标准本身.


Jim*_*myB 5

这里不使用动态堆内存分配的主要原因基本上是:

a)确定性和相关性,b)记忆碎片化.

在那些小型嵌入式应用程序中,内存泄漏通常不是问题,因为它们将在开发/测试的早期检测到.

然而,内存碎片可能变得不确定,导致(最佳情况)随机时间内的内存不足错误以及现场应用程序中的点.

在动态分配开发期间预测应用程序的实际最大内存使用量也可能是非常重要的,而静态分配内存的数量在编译时是已知的,并且检查该内存是否可以由硬件与否.