繁体   English   中英

实时应用中malloc的使用

[英]Use of malloc in Real Time application

我们的一个实时应用程序有问题。 这个想法是每 2 毫秒(500 赫兹)运行一个线程。 应用程序运行了半小时或一个小时后……我们注意到线程落后了。

经过几次讨论,人们抱怨实时线程中的 malloc 分配或根本原因是 malloc 分配。

我想知道,在实时线程中避免所有动态内存分配总是一个好主意吗?

互联网上很少有这方面的资源? 如果你能指出一些讨论,我们也会很棒..

谢谢

第一步是分析代码并确保您准确了解瓶颈所在。 人们通常不擅长猜测代码中的瓶颈,您可能会对这些发现感到惊讶。 您可以自己简单地检测此例程的几个部分,并定期转储最小/平均/最大持续时间。 您希望看到最坏的情况(最大值),以及平均持续时间是否随着时间的推移而增加。

我怀疑malloc是否会在能够运行 Linux 的合理微控制器上占用这 2ms 的任何重要部分; 我想说的是,与性能问题相比,由于碎片而导致内存不足的可能性更大。 如果您的函数中有任何其他系统调用,它们将很容易比malloc一个数量级。

但是,如果malloc确实是问题所在,取决于您的对象的生命周期有多短、您可以浪费多少内存以及您提前知道多少您的需求,您可以采取以下几种方法:

  1. 通用分配(来自您的标准库或任何第三方实现的malloc ):如果您拥有“足够多”的 RAM、许多短期对象且没有严格的延迟要求,则是最佳方法

    • 优点:适用于任何开箱即用的对象大小,熟悉的界面,动态共享内存,如果内存不是问题,则无需“提前计划”
    • 缺点:分配和/或解除分配期间的轻微性能损失,对不同大小的对象进行大量分配/解除分配时的内存碎片问题,运行时分配是否会失败不太确定并且在运行时不能轻易缓解
  2. 内存池:大多数情况下内存有限、需要低延迟并且对象需要比单个块作用域存活时间更长的最佳方法

    • 优点:在任何合理的实现中,分配/释放时间都保证为O(1) ,不会受到碎片的影响,更容易提前计划其大小,在运行时分配失败(可能)更容易缓解
    • 缺点:适用于单个特定对象大小 - 程序的其他部分之间不共享内存,需要规划正确大小的池或存在潜在的内存浪费风险
  3. 基于堆栈的(自动持续时间)对象:最适合更小、寿命短的对象(单块范围)

    • 优点:分配和释放是自动完成的,允许在对象的生命周期内优化使用 RAM,有一些工具有时可以对代码进行静态分析并估计堆栈大小
    • 缺点:对象仅限于单个块范围 - 不能在中断调用之间共享对象
  4. 单个静态分配的对象:长寿命对象的最佳方法

    • 优点:没有任何分配——所有需要的对象在整个应用程序生命周期中都存在,分配/释放没有问题
    • 缺点:如果对象应该是短暂的,则会浪费内存

即使您决定在整个程序中使用内存池,也要确保将分析/检测添加到您的代码中。 然后将它永远留在那里,看看性能如何随时间变化。

作为航空航天行业的实时软件工程师,我们经常看到这个问题。 即使在我们自己的工程师中,我们也看到软件工程师试图使用他们在别处学到的非实时编程技术或在他们的程序中使用开源代码。 切勿在实时期间从堆分配。 我们的一位工程师创建了一个工具来拦截 malloc 并记录开销。 您可以在数字中看到,您无法预测分配尝试何时需要很长时间。 即使在运行实时混合 Linux 的非常高端的计算机(72 核,256 GB RAM 服务器)上,我们也记录了花费 100 毫秒的 malloc。 这是一个跨环的系统调用,开销如此之大,而且您不知道什么时候会被垃圾回收击中,或者什么时候它决定必须为操作系统的任务请求另一个大块或内存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM