为什么内存分配弹性对物联网至关重要
这是非常不同的,但是,当谈到物联网。在这些嵌入式连接设备中,内存是一种有限的资源,多个程序会争夺它们可以消耗多少内存。系统更小,内存也更小。因此,它最好被视为一种有限的资源,保守地使用。
正是在这种背景下,内存分配(也称为malloc)在我们的领域中变得非常重要。Malloc是在执行程序或进程时保留一部分计算机内存的过程。把事情做好,尤其是对于连接到互联网的设备而言,可以决定性能的好坏。
因此,让我们来看看开发人员如何将弹性构建到他们的malloc方法中,以及这对未来的连接设备性能意味着什么。
Malloc和连接设备:简史
让我们从头开始。传统上,malloc在嵌入式系统中不常使用。这是因为旧设备通常不连接互联网,因此对内存的需求差异很大。
然而,这些较旧的设备在系统启动时创建了一个资源池来分配资源。资源可以是一个连接,系统可以被配置为允许来自静态分配池的n个连接。
在一个非互联网连接的系统中,系统的状态通常受到一定的限制,因此内存分配的上限更容易估计。但是,一旦嵌入式系统连接到互联网,这种情况就会彻底改变。
例如,一个设备可以计算多个连接,并且每个连接可以根据其用途而有不同的内存需求。这里,连接上的数据流所需的缓冲存储器取决于连接的等待时间,以使用针对分组丢失或其他网络相关行为的某种概率函数来获得特定吞吐量。
这在现代高端系统上通常不是问题。但是,请记住,开发人员在嵌入式环境中面临着有限的内存资源。所以,你不能简单地假设有足够的内存。
这就是为什么在物联网嵌入式开发中,考虑如何创建对内存分配错误(也称为malloc失败)具有弹性的软件非常重要。
现代嵌入式连接系统和Malloc
在…里现代互联嵌入式系统,malloc被更频繁地使用,许多嵌入式系统和平台都有不错的malloc实现。这种转变的原因是现代连接的嵌入式系统执行更多的任务,并且为程序的所有可能的执行静态地分配最大的所需资源通常是不可行的。
这种在现代互联嵌入式系统中积极使用malloc的转变需要更彻底、更系统的软件测试来发现错误。
通常,分配错误不会被系统地测试,因为它经常被认为是以如此小的概率发生的事情,以至于不值得努力。由于分配错误非常罕见,任何bug在被发现之前都可以存活数年。
Mallocfail:如何测试错误
好消息是开发人员可以利用软件来测试分配错误。一种新颖的方法是运行一个程序,并在发生分配的所有唯一执行路径中注入分配错误。这可以通过工具来实现mallocfail.
顾名思义,Mallocfail有助于以确定的方式测试malloc故障。该工具不是随机测试,而是自动枚举malloc故障的不同控制路径。它的灵感来自于此堆栈溢出答案.
简而言之,这个工具用定制版本覆盖了malloc、calloc和realloc。每次自定义分配器运行时,该函数使用libbacktrace生成当前调用堆栈的文本表示,然后生成该文本的sha256散列。
然后,该工具检查是否已经看到了新的散列。如果从未见过,则内存分配失败。哈希存储在内存中,并写入磁盘。如果这个散列——特定的调用栈——以前已经出现过,那么正常的libc版本的分配器将被正常调用。每次程序启动时,已经看到的哈希值都会从磁盘加载进来。
这是我第一次使用的东西,发现非常有用。例如,在我的公司,我们在我们的嵌入式edge软件开发套件。我很高兴地报告,该工具实际上成功地识别了SDK及其第三方库中的一些问题。因此,前一个问题现已修复,后一个问题已得到修补。
处理Malloc失败
在复杂的系统中,处理分配错误可能有点棘手。例如,考虑需要分配数据来处理一个事件。存在不同的模式来解决这个问题。最重要的是分配必要的内存,以便在分配失败的情况下可以将错误传递回程序,并且某些代码路径不会无声无息地失败。
处理malloc失败的能力是我的团队经常考虑的事情。当然,这在其他设备上不是什么大问题,但在连接到互联网的嵌入式设备上可能会造成大问题。
出于这个原因,我们的SDK计算功能来限制某些资源,包括连接、流、流缓冲区等等。这使得系统可以被配置为限制所使用的内存量,从而不太可能发生malloc错误(并且这只是一个资源分配错误)。
通常,系统内存不足会导致系统运行困难。所以降低分配错误的概率是很有意义的。这通常通过限制哪些功能/任务可以同时发生来处理。
作为一个在这个领域工作了20年的人,我相信当涉及到现代嵌入式连接设备时,开发人员应该采用最佳malloc实践。