首页 > 嵌入式基础教程 > 基础知识

所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。

关于静态内存与动态内存

1.1、静态和动态内存的特点

在探讨这个问题之前我们先来对比下静态内存和动态内存的特点:

1. 创建的时间不同: 创建的时间不同:静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。

1.png

编译链接过程中已经分配好的

代码运行过程中使用rt_malloc分配:

1static void onmessage_text(rws_socket socket, const char *text, const unsigned int len)

2{

3 char *buff = RT_NULL;

4

5 buff = (char *)rt_malloc(2048);

6

7 rt_memset(buff, 0x00, 2048);

8 rt_memcpy(buff, text, len);

9

10 LOG_D("message(txt), %d(byte): %s ", len, buff);

11

12 if(buff != RT_NULL)

13 {

14 rt_free(buff);

15 }

16}

2. 创建的空间不同:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由函数malloc进行分配。不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。

1.2、静态和动态内存的优缺点

2.png

在了解了静态内存和动态内存不同的特点后可以分析出它们在不同的方面具有不同的优缺点:

1.静态内存编译阶段就分配好了,不会存在分配失败的情况,除非系统内存被分配完了,但是在编译阶段就可以查出。动态内存在运行中分配,在正常运行的情况下可能够正常分配,在某种环境下可能分配失败 ,这样就对开发者的代码水平要求更高,要求开发者需要对代码的健壮性有要求。

2.静态内存由于是编译阶段分配好的,而动态内存是由运行中分配,这样动态内存可以被高效复用,当某段程序使用完毕后,可以将内存交换给内存池中等待下次程序的分配,由于这种机制,开发者可以利用更小的内存开发更大型的程序。

3. 动态内存由于是动态分配,所以涉及到分配和释放的问题,假设X程序在分配了ABC3块内存,程序执行完毕后AC区域内存被释放,但是由于开发者的疏忽导致B区域的内存被遗留。而X程序又是会被反复调用的,这样我们的内存区域由于有没有释放的区域导致每次调用就会占用一段区域,最终系统就没有内存可以使用。这种情况一般在产品实际体现为最开始的时候设备正常工作,但是运行了几个小时或者几天后死机。这种情况一般被称作内存泄漏(Memory Leak)。

4. 在嵌入式RTOS中线程函数中使用静态内存,也就是在线程中定义局部变量,会加大线程栈空间的开销。

裸机开发和RTOS开发的特点

1. 代码规模:裸机开发的项目一般代码规模度都比较小,对于一般开发者都难于驾驭使用裸机开发超大规模项目,人力成本和时间成本都太高。反而由于RTOS的模块化特性,更容易开发出代码规模大的项目。

2. 系统稳定性:在机电,航空,汽车等行业都是需要高实时性、高稳定性和高安全性的。对于RTOS来说,系统任务的划分调度都是系统管理,当开发者对其机制了解不清楚的情况下反而带来了部分风险。除此之外RTOS上的内存管理也是很大影响系统的,对于RTOS上一般不会存在MMU内存管理单元,也就代表大部分运行RTOS的芯片上都没有虚拟地址映射,那么就无法利用物理地址和虚拟地址的特性进行内存整理,避免内存泄漏。所以说在RTOS动态内存这块内存有风险。

嵌入式中是否应该使用动态内存

明白不同内存的优缺点和裸机RTOS的特点之后,我们在回头来分析 “嵌入式中是否应该使用动态内存?” 这个问题。在实时嵌入式系统中,由于系统软件并不像PC上复杂,一般都是很简单的内存使用,所以一般也不使用动态内存管理,但是随着RTOS面临的任务越来越重,尤其是IoT和AIoT的到来,让许多消费级产品运行的RTOS的负担越来越重。在这种情况下继续使用静态内存开发会极大的限制开发进度,整个开发的灵活性非常低。同时静态的内存无法复用使用同一片内存区域,相比与动态内存在大型项目中一般会使用更多的内存,在内存大小不容乐观的嵌入式系统是很难接受的。但是针对一些高稳定性和高安全性的项目来说,使用动态内存就需要好好斟酌下,由于RTOS上基本没有MMU的硬件支持或者是系统软件支持,所以不可避免的系统中会出现内存碎片,从而有可能导致系统异常。最终说了这么多总结成以下几点:

1. 没有使用RTOS的项目:不建议使用动态内存,这种项目一般很简单,不必使用动态内存增大系统开销和复杂度。

2. 使用RTOS的消费级项目:建议使用动态内存,一般这种项目代码复杂度比裸机高,合理使用动态内存会有效降低内存的开销。同时很多Github项目的linux程序都是会使用内存管理,有这套机制能更加方便的移植代码。

3. 使用RTOS的军工、航天、医疗等高稳定性和高安全性项目:建议尽量降低对动态内存的使用与依赖以确保系统的稳定性。当然也不代表动态内存就无法在这些项目上使用,只是要求系统开发者对系统内存的把控要求更高。

RT-Thread的内存管理

RT-Thread 操作系统在内存管理上,根据上层应用及系统资源的不同,有针对性地提供了不同的内存分配管理算法。总体上可分为两类:内存堆管理与内存池管理,而内存堆管理又根据具体内存设备划分为三种情况:

第一种是针对小内存块的分配管理(小内存管理算法);

第二种是针对大内存块的分配管理(slab 管理算法);

第三种是针对多内存堆的分配情况(memheap 管理算法)。

小内存管理算法是一个简单的内存分配算法。初始时,它是一块大的内存。当需要分配内存块时,将从这个大的内存块上分割出相匹配的内存块,然后把分割出来的空闲内存块还回给堆管理系统中。每个内存块都包含一个管理用的数据头,通过这个头把使用块与空闲块用双向链表的方式链接起来。

RT-Thread 的 slab 分配器是在 DragonFly BSD 创始人 Matthew Dillon 实现的 slab 分配器基础上,针对嵌入式系统优化的内存分配算法。最原始的 slab 算法是 Jeff Bonwick 为 Solaris 操作系统而引入的一种高效内核内存分配算法。

memheap 管理算法适用于系统含有多个地址可不连续的内存堆。使用 memheap 内存管理可以简化系统存在多个内存堆时的使用:当系统中存在多个内存堆的时候,用户只需要在系统初始化时将多个所需的 memheap 初始化,并开启 memheap 功能就可以很方便地把多个 memheap(地址可不连续)粘合起来用于系统的 heap 分配。

换一批

延伸阅读

[行业资讯] 前景不明,内存现货大涨24% 合约价再跌10%

前景不明,内存现货大涨24% 合约价再跌10%

三星前两天发布的财报中,Q2季度盈利暴跌连53%,主要原因就是内存跌价所致。三星表示随着数据中心市场的客户调整库存,内存芯片的需求疲软及价格下跌因素依然存在,预计今年剩余的时间内业务存在不确定性。尽管内存价格存在不确定性,还有遭遇日本政府对......

关键字:三星 内存 芯片

[行业资讯] 内存价格疯涨背后的阴谋阳谋,谁会成为最后赢家?

内存价格疯涨背后的阴谋阳谋,谁会成为最后赢家?

日韩突发贸易战,引得存储器价格狂涨,普通消费者叫苦不迭。这背后,究竟隐藏着怎样的阴谋阳谋?潮流向左,DIY 向右。在这个电子产品日新月异的时代,总有些极客玩家喜欢特立独行,自己摆弄些 DIY 产品。DIY 全称 Do it Yourself......

关键字:存储器 内存 智能手机

[行业资讯] 高效低耗计算机系统大行其道,传统架构如何展露才华?

高效低耗计算机系统大行其道,传统架构如何展露才华?

随着物联网时代的到来,海量的数据蜂拥而至。特别是各种应用终端和边缘侧需要处理的数据越来越多,而且对处理器的稳定性,以及功耗提出了越来越高的要求,这样,传统的计算体系和架构的短板就显得愈加突出,未来,具有更高效率和更低功耗的计算系统一定会大行......

关键字:物联网 芯片 内存

[行业资讯] 价格持续疲软,DRAM市场资本开支将大幅减少

价格持续疲软,DRAM市场资本开支将大幅减少

最近内存市场(闪存也一样)出现了多种复杂因素,除了全球贸易这个大环境因素之外,还有内存不断跌价、日韩半导体材料纠纷等问题,原本预期Q3季度内存还会继续跌15%的价格,但上周内存现货价格出现了10个月来首次上涨。 ......

关键字:内存 闪存 DRAM

[行业资讯] DRAM 内存芯片连跌三季度,今年下半年能否恢复正常?

DRAM 内存芯片连跌三季度,今年下半年能否恢复正常?

DRAM内存芯片也连跌三个季度了,三星、美光、SK Hynix公司内存业务的营收及盈利大幅下滑,不得不削减产能以减少供应,业界预期下半年内存市场会恢复正常。Winbond华邦电子上周末召开了股东会,董事长焦佑钧表示内存芯片供不应求的时代过去......

关键字:DRAM 内存 芯片
条评论

我 要 评 论

网友评论

大家都爱看