C语言的ios内存管理安卓区别与UCOS的ios内存管理安卓区别有什么区别

详解UCOS中的ios内存管理安卓区别

在嵌叺式设备中持续的调用malloc()和free()容易产生内存碎片,长时间的运行最终会导致内存消耗殆尽UCOS提供了一套ios内存管理安卓区别机制,在系统初始囮的时候就分配好内存空间将所有可用的空间组织成链表,需要申请内存的时候直接从链表中申请释放内存的时候直接将内存归还到涳余内存链表中即可。使用这种方法不仅避免了内存碎片的产生而且使得在常数时间内分配内存空间成为可能。

UCOS中ios内存管理安卓区别的結构体是OS_MEM具体结构如下:

在UCOS中,一个内存分区被划分成很多个大小相等的内存块这些内存块链接成链表,链表的表头存于OSMemFreeList中

比如一個有4个内存块,每个内存块128bit的内存分区Memoy如下:

UCOS的思路是我们将要分配的空间组织成二维数组然后二维数组的每一行就是一个block,二维数组嘚列数既是block的大小

为了管理方便我们在每一个block的开头存储下一个block的地址,这样就把所有的block串接成了单链表

UCOS中创建内存分区的核心代码洳下(代码取自OSMemCreate):

上述代码的核心就在于*pblink = (void*)pblk;每一个block开头存放下一个block的地址,这样便把所有的block组织成了一条链表
}

【@.1 指针与动态ios内存管理安卓区别】

在C语言中的指针若不经过初始化是无法进行操作的在编译时甚至不会报错,但是一旦运行到这里时就会出现程序错误死机所以对于指针的操作一定要首先初始化再赋值。考虑如下代码:

当运行到pdata赋值时由于没有初始化程序必死。当然这还是比较明显的错误若指针被封装在结构或联合中就不用已发现了,比如如下代码:

上面程序可能不会报错而且打印的东西跟pNodes没关系,但实际运行程序会死掉关鍵就是那句pNodes->node的赋值句,这里看上去是第一次给pNodes赋值以为是初始化,但是实际上操作了一个没有初始化的内存地址程序会死机好的方式昰想下面这样写主函数(其余部分一样):

这里直接将Node1的地址复制给pNodes,此时pNodes才能被正常初始化所以一般我们在程序中会采取动态内存分配的方式申请内存空间,为指针型变量分配内存比如如下代码:

调用malloc函数之后就可以随便操作这个指针变量了。可以看malloc的具体使用方法但昰这种malloc函数是一种平台相关函数,不同的CPU不同的操作系统的具体实现内容不一样。另外对于嵌入式系统来说写代码时调用这类函数并鈈妥当,可能会使本来就吃紧的内存被分割成许多小而不连续的内存块因此若编写嵌入式代码,甚至是编写PC代码时想自己手动了解变量汾配的机制并加以ios内存管理安卓区别时可以考虑自己编写这类ios内存管理安卓区别分配的代码。以下的代码就实现了这一功能编程思想哏uCOS-II中的一模一样,你可以看做是一个uCOS-II中ios内存管理安卓区别的分析但是这种机制完全可以在PC机上使用,而实际上我的代码测试也是在window下完荿的如果你手上没有一个纯洁的C语言编译器,可以参考我的利用gcc来进行C语言编译

【@.2 uCOS-II中动态ios内存管理安卓区别的C语言实现】

嵌入式编程仳较关心的就是内存大小,在有限的内存中实现动态和静态的代码分配是有学问的对于像malloc()这类在运行时从堆(heap)中请求内存的函数,若调用佽数太多可能会造成内存的快速消耗殆尽一个比较好的放大是,放弃使用malloc系列函数将所有将要运行时分配的空间计算好,利用全局变量分配到静态代码空间中实际使用时调用自己编写好的ios内存管理安卓区别函数从这块静态空间中申请内存。这样的一个最大的好处是內存的总体大小是受控的,所有涉及到动态分配内存的地方实际上都已经被预先分配好在编译时写在静态代码区(利用全局变量)。若对于程序静态和动态的内存需求还不清楚的可以参考我的有一个比较简单但是通俗易懂的介绍因此,第一步需要做的事就是申请一个全局变量存放将要动态分配的内存比如下面的全局变量申明:

这里采用了二维数组。利用一维数组构建了ios内存管理安卓区别机制可以参考。對于二维数组左边的可以看做分区,右边的下标可以看做是在不同分区中的内存块但是整个数组在内存空间中还是线性分布的,可参栲如下图示:

每个这样的二维数组就可以看成是一个连续的内存空间如果程序要求层次结构不高,在程序中甚至可以仅仅包含这一个二維数组只要计算好大小即可。

有了这样的二维数组之后还需要另一个ios内存管理安卓区别块来对这片内存进行管理,如下定义:

前面代碼中的两个控制块这里只画了一个每个ios内存管理安卓区别块中记录了对应存储的数组地址(EntryAddr),当前可用的数组的地址(FreeAddr)当内存进行分配时,这一位会进行偏移操作指向还未被分配的存储数组。而这些管理块也需要一个总的数组来存储其位置(MMUPool[ ])否则这些指针也是无法初始化嘚指针。并且新建一个指针(*MMUFree)指向当前还未被分配的可以用的管理块数组中位置。

图中红色的就是实际存储的数组可以看出核心思想是,所有需要实际存储的指针都由数组来保存所有指针最终均指向一个实际的变量。若要使用这种ios内存管理安卓区别第一步要做的昰初始化MMUPool,调用MemInit()之后将内部所有的成员形成一个链表由MMUFree指向最开头的一个。

这样一来就可以为ios内存管理安卓区别块分配一个实际的对象叻调用MemCreate()可以分配一个实际的对象给ios内存管理安卓区别块并且将ios内存管理安卓区别块与实际的内存存储区联系在一起

这一步之后就可以分配实际的内存给指针了,比如如下代码:

当最后不用这篇内存时一定要记得调用MemFree()回收这篇内存空间,不然这片内存空间将会越来越小导致无法再次使用这篇内存空间所以这也是C语言没有垃圾回收机制的一个弊端,虽然我们很多时候并没有注意这件事但是一旦程序编的佷长,这些内存的细节就不得不注意了

这种手动内存回收没有重新清零,所以当下次再分配内存时将会把这篇包含数据的使用过的内存汾配给新的对象有可能造成内存泄露。而实际上在uCOS-II源代码中并没有进行重新清零的操作,当然像工业控制中这类问题不是很重要所鉯可以忽略。而若要编写实际的操作系统这种简单的回收机制就不适用了。

整个完整的流程可以用下面的C代码写出这里的实现思想基夲跟uCOS-II中的一样,但是可以在PC上进行编译这样测试的效果也很明显。注意有的C++编译器可能会报错(比如Visual Studio)可以参考我的使用gcc的C编译器来測试。

}

只要你程序中变量都是全局的(茬静态数据区)或自动的(在栈上)完全可以不要ios内存管理安卓区别。

你对这个回答的评价是

}

我要回帖

更多关于 ios内存管理安卓区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信