0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式开发是否应该使用动态内存分配

刘伟 来源:felixbury 作者:felixbury 2022-07-15 14:16 次阅读

我遇到的许多嵌入式软件开发人员提出的一个我觉得特别有趣的话题是动态内存分配——在需要时获取内存块。这种看似简单和常规的操作会带来大量问题。这些并不局限于嵌入式开发——许多桌面应用程序都会出现内存泄漏,这会影响性能,并且会使系统重新启动很常见。但是,我担心嵌入式开发环境。

poYBAGLPACmALFTBAAC-mYoMJZ0343.png

poYBAGLPACmALFTBAAC-mYoMJZ0343.png

通常不建议将malloc()用于嵌入式应用程序的原因有很多:

  • 该函数通常不可重入(线程友好),因此将其与实时操作系统一起使用可能具有挑战性。
  • 它的性能不是确定性的(可预测的),因此分配一个内存块所花费的时间可能是非常可变的,这在实时应用程序中是一个挑战。
  • 内存分配可能会失败。

尽管这些都是有效的观点,但它们可能并不像看起来那么重要。

仅当从多个线程调用函数时,重入才是一个问题。编写一个可重入的malloc()函数是非常可行的,但也可以使用标准版本以使重入变得不必要。只需将所有内存分配活动本地化为单个任务。您甚至可以创建一个唯一功能是动态内存分配的任务;其他任务将简单地发送一条消息,请求分配或释放内存块。

并不总是需要确定性。并非应用程序是实时的,并且那些不一定需要对其操作的所有部分确定性的应用程序。

分配失败可能是个问题,但可以管理。如果malloc()函数无法分配所请求的内存,则它会返回一个空指针。必须检查此响应并采取适当的措施。如果失败是由于内存耗尽,很可能是设计缺陷——没有为堆分配足够的内存。然而,分配失败的一个常见原因是堆碎片。有足够的可用内存,但它不在连续区域中。这种碎片的出现是因为内存以随机方式分配和释放,从而导致内存的分配和空闲区域。有两种方法可以消除碎片:

首先,如果应用程序允许,只需确保使用遵循这种模式的代码按顺序完成分配和释放:

a = malloc(1000);
b = malloc(100);
c = malloc(5000);
...
免费(c);
免费(乙);
免费(一);

当然,这通常是不可能的。因此,需要另一种选择。

事实证明,许多应用程序并不需要malloc()提供的所有灵活性。所需的内存块具有固定大小(或少量不同大小)。为固定大小的块编写内存分配器非常简单;这消除了碎片化,如果需要,可以很容易地确定性。毫不奇怪,大多数 RTOS 都有以这种方式分配内存块的服务调用。

不管它的不可预测性如何, malloc()还有另一个问题——它往往相当慢。这并不奇怪,因为该函数的功能非常复杂。基于块的分配器的内在简单性非常有效地解决了这个问题。

但是,如果应用程序在不可预测的时间确实需要随机大小的内存块怎么办?

实现这种灵活性同时避免碎片和不确定性的一种方法是构建一个分配器,根据请求的内存块大小从多个“池”中选择块。为池选择块大小的一个好方法(如果您事先不知道需要的块大小)是使用几何系列,如 16、32、64、128 字节。然后分配将像这样工作:

poYBAGLPAC6AW3BSAARZ-8D01G4506.png

poYBAGLPAC6AW3BSAARZ-8D01G4506.png

显然,一些分配会非常有效:16 字节池中的 16 字节。有些会非常好;来自 32 字节池的 31 个字节。其他人会没事的;来自 16 字节池的 9 个字节。还有一些效率低下;来自 128 字节池的 65 个字节。总体而言,这些低效率是为速度、确定性和消除碎片化的好处付出的小代价。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4981

    文章

    18265

    浏览量

    288215
  • 应用程序
    +关注

    关注

    37

    文章

    3132

    浏览量

    56359
  • 内存分配
    +关注

    关注

    0

    文章

    16

    浏览量

    8265
收藏 人收藏

    评论

    相关推荐

    C语言知识总结:动态内存分配

    动态内存分配就 是指在程序执行的过程中动态分配或者回收存储空间的分配内存的方法。
    发表于 10-24 15:52 652次阅读

    使用C语言实现简单动态内存分配

    首先要明白为何需要动态内存分配,熟悉C语言的读者应该对这个比较熟悉,需要一段内存时会使用malloc函数来申请所需要大小的内存,函数返回一段
    发表于 07-28 16:26 387次阅读
    使用C语言实现简单<b class='flag-5'>动态内存</b><b class='flag-5'>分配</b>

    动态内存管理的原理详解

    错误。而相比于个人计算机,嵌入式系统的内存资源更是稀缺。作为嵌入式C的开发人员,了解其内存管理的原理能使其更加正确地使用
    发表于 11-02 09:25

    内存动态内存分配实现

    第27章 STM32H7的TCM,SRAM等五块内存动态内存分配实现本章教程为大家分享一种DTCM,SRAM1,SRAM2,SRAM3和SRAM4可以独立管理的动态内存管理方案,在实
    发表于 08-03 07:14

    嵌入式C语言动态内存分配

    动态内存分配:1、malloc、memset、free在日常写代码时需要注意以下几点:malloc分配内存时,需要 if语句 判断malloc是否
    发表于 12-14 06:37

    请问使用动态内存分配安全吗?

    在使用完毕后,需要显的释放之,这就要求程序员对动态分配内存了然于胸。在非常重视安全(safety-critical)的嵌入式C语言程序开发
    发表于 12-15 06:10

    使用动态内存分配安全吗

    安全吗?”为了更加安全稳定,美国军方禁止在C语言程序中使用malloc()使用动态内存分配安全吗?在C语言程序开发中,动态内存分配允许程序在
    发表于 12-15 07:44

    动态内存分配是什么意思

    所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态分配或者回收存储空间的分配
    发表于 12-17 08:17

    RTThread的动态内存空间该如何去分配

    的Heap_Size,而使用rt_malloc申请到的则是RTT分配的空间然后有以下几个问题1、如果是动态创建线程,那线程中的局部变量是位于RTT分配动态内存空间中还是位于栈空间中?
    发表于 08-31 14:34

    一种新的嵌入式实时动态内存管理结构

             内存资源是嵌入式操作系统中需要管理的重要资源之一。这种O(1)时间复杂度的嵌入式实时动态内存
    发表于 09-10 10:20 16次下载

    基于Core的动态内存分配方案

    为了解决基于C*Core系列芯片嵌入式开发过程中,C*Core系统在某些情况下由于受操作系统、数据格式差异等因素影响,不能动态分配C*Core系列芯片内存的问题,采用数组与标志位相结合的
    发表于 07-11 10:37 38次下载
    基于Core的<b class='flag-5'>动态内存</b><b class='flag-5'>分配</b>方案

    动态内存管理在面向嵌入式实时系统中的研究

    动态内存管理的基本任务就是有效地对动态内存进行分配、回收,并同时保证系统的快速性、可靠性和稳定性。当系统请求分配内存时,系统需要从所有空闲块
    发表于 07-22 11:14 986次阅读

    嵌入式中需要用到动态内存

    所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态分配或者回收存储空间的分配
    的头像 发表于 07-27 08:11 2861次阅读

    嵌入式C语言中的动态内存管理和动态内存分配

    动态内存管理同时还具有一个优点:当程序在具有更多内存的系统上需要处理更多数据时,不需要重写程序。
    发表于 08-15 17:16 1979次阅读

    嵌入式是否使用动态内存?

    嵌入式是否应该使用动态内存?
    的头像 发表于 02-28 17:03 1508次阅读