越来越多的嵌入式软件开发人员意识到动态内存分配——在需要时获取大块内存并在以后放弃它们——虽然方便灵活,但也充满了问题。这些问题不仅限于嵌入式代码,许多桌面应用程序都存在影响性能和可靠性的内存泄漏。但在这里我想专注于嵌入式。
质疑使用标准malloc()库函数的三个关键原因:
内存分配可能会失败。这可能是因为没有足够的可用内存(在堆中)来满足请求。也可能是碎片造成的;有足够的可用内存,但没有连续的块足够大。
该函数通常是不可重入的。在多线程(多任务)系统中,如果函数被多个任务调用,则它们必须是可重入的。这确保了,如果调用被中断,对该函数的另一次调用不会危及第一次调用。
它不是确定性的。在实时系统中,可预测性(确定性)至关重要。标准malloc()函数的执行时间非常多变且无法预测。
这些都是有效的点,并且有解决它们的方法,这通常是使用实时操作系统 (RTOS) 提供的功能的问题。
然而,尽管它们是有效的,但问题可能并不总是像看起来那么重要:
如果发生分配失败,该函数将返回一个NULL指针。这很容易检查,并且可以采取行动。
在许多应用程序中,所有内存分配和释放都在单个任务中执行。这使得重入是不必要的。
并非所有嵌入式系统都是实时的,因此可能不需要确定性。
malloc()可能会带来另一个挑战:它相当慢。一些系统需要速度,而不是可预测性,因此需要考虑找到一种方法来提供此功能的功能并具有更高的性能。
该函数性能不佳的主要原因是它提供了很多功能。不同大小的内存块的管理是相当复杂的。对于许多应用程序来说,这实际上是多余的,因为所需的内存分配都是相同的大小(或少量不同的已知大小)。为固定大小的块编写内存分配器非常简单;只是一个带有使用标志的数组或者一个链表。代码肯定会更快,甚至可以确定地完成。分配失败仍然可能发生,但管理起来很简单。这种类型的内存分配通常由流行的 RTOS 产品提供。
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !