安全关键项目中动态分配的替代方案 (C)

Alternatives to dynamic allocations in safety critical projects (C)

安全关键项目不建议任何动态分配或释放分配的内存。只有在程序执行的 elaboration/initialization 阶段,才允许。

我知道你们中的大多数人会争论实现 SW 的方式是它应该只进行所有静态分配,或者在代码中做一些证明动态分配不会损害整个程序的理由,等等,但是还有其他选择吗这个问题?有没有什么方法或例子可以在程序 initialization/elaboration 和 allocate/deallocate 内存期间分配一些(堆)内存?或者如果我们真的想在(安全关键的)项目中进行动态分配,这个问题有任何 solutions/alternatives 吗?

此类问题最常被开发人员问到,他们希望能够在没有 "undue" 限制的安全相关系统中使用动态内存分配 - 这通常似乎意味着他们不会被阻止在他们选择的时候按他们选择的数量动态分配内存,并(可能)在他们选择的时候释放内存。

我先解决这个问题(动态内存分配可以不受限制地用于关键系统吗?)。然后我会回到选项,涉及接受一些关于如何(何时或是否)使用动态内存分配的限制。

在一个"safety critical project"之内,这样的事情一般是不可能的。安全相关系统通常具有与减轻或消除特定危险有关的强制性要求。未能充分减轻或消除指定的危险(即满足要求)可能会导致伤害 - 例如,人员死亡或受伤。在这样的系统中,通常需要在某种程度上严格地确定危害是否得到适当和可靠的减轻或消除。其结果通常是一组与确定性相关的要求 - 通过适当的分析确定系统以指定方式完成操作的能力 - 其中行为和时间等属性被严格指定。

如果不受限制地使用动态内存分配,则很难确定系统的某些部分是否按要求运行。问题类型包括;

  • 未分配内存的碎片。无法确保分配 N 个连续字节内存的请求会成功,即使有 N 个字节的内存可用。如果之前以任意顺序进行了多次分配和取消分配,则尤其如此 - 即使有 N 字节的内存可用,它们也可能不在连续的包裹中。
  • 充足。通常很难保证必须成功的关键内存分配确实成功。
  • 适当释放。很难防止内存在仍然需要时被释放(导致可能访问已被释放的内存)或确保内存不被释放不再需要实际释放(例如防止内存泄漏)。
  • 及时性。 缓解上述问题的尝试意味着分配或解除分配的时间是可变的、不可预测的,并且可能没有上限。处理这些问题的方法示例是碎片整理(处理碎片问题)或垃圾收集(处理足够 and/or 的问题并适当发布)。这些过程需要时间和其他系统资源。如果它们在尝试分配时完成,则分配内存的时间将变得不可预测。如果它们在释放内存时完成,则释放内存的时间变得不可预测。如果它们在其他时间完成,其他(可能是关键的)代码的行为可能会变得不可预测(例如,应用程序的世界实际上冻结了)。

所有这些因素,以及更多因素,意味着不受限制的动态内存分配在系统时序或资源使用的确定性要求下不能很好地工作。本质上,系统要求需要施加一些限制,并根据系统强制执行。

如果可以接受对动态内存分配的限制,还有其他选择。通常,这些技术需要政策约束和技术解决方案方面的支持,以鼓励(最好是在高关键性系统中强制执行)遵守这些政策。策略执行可能是技术性的(例如自动和手动设计和代码审查、定制的开发环境、合规性测试等)或组织性的(例如解雇故意绕过关键策略的开发人员)。

技术示例包括;

  • 根本没有动态分配。 即只有静态分配。
  • 只在系统初始化时使用动态内存分配。这需要预先确定需要分配的最大内存量。如果内存分配失败,请将其视为任何 POST(开机自检)失败。
  • 分配内存但从不释放它。这往往可以避免碎片化问题,但会使确定系统需要多少内存的上限变得更加困难.
  • 自定义分配。系统(或应用程序)显式管理动态内存分配,而不是使用通用库函数(例如与所选编程语言相关的函数)。这通常意味着引入自定义分配器并禁止(或禁用)使用通用库函数进行动态内存管理。自定义分配器必须根据特定系统的需求明确设计。
  • 内存管理中的装箱。这是一种特殊类型的自定义分配,其中应用程序分配内存池,函数请求固定数量(或固定数量的倍数)从游泳池。因为池是由应用程序固定的,所以应用程序会监视池中有多少内存在使用中,并在内存耗尽时采取措施释放内存。池中的分配和解除分配也可以按预期执行(因为正在管理动态内存分配的一些更普遍的问题)。关键系统可能有多个池,每个池专供特定功能集使用。
  • 分区。 明确阻止非关键函数访问已建立供关键函数使用的内存池。这可以确保关键功能可以访问所需的内存,还有助于确保低关键功能的故障不会触发高关键功能的故障。分区可以在应用程序内执行,或在(适当认证的)主机操作系统内执行,或两者都执行......取决于系统的需要。

其中一些方法可以相互支持。