薛楠 李斌 王曉華 楊明偉 杜建華
摘要:在嵌入式軟件開發(fā)和設(shè)計中,軟件的安全性和穩(wěn)定性是非常重要的,一個大型的嵌入式軟件是由各個不同功能的軟件子系統(tǒng)構(gòu)成的[1]。在眾多不同功能的軟件子系統(tǒng)中,內(nèi)存管理功能模塊是最重要的子功能模塊,也是其他子功能模塊的基礎(chǔ)[2]。該文提出了一種基于動態(tài)內(nèi)存管理和分配的雙向鏈表管理方式,在動態(tài)給定存儲地址和空間大小基礎(chǔ)上,根據(jù)實際需要,將存儲空間作為內(nèi)存池進行動態(tài)管理,實現(xiàn)功能包括動態(tài)的內(nèi)存申請和釋放,以及給定地址內(nèi)存塊的查詢,高效、動態(tài)地對內(nèi)存空間進行操作。
關(guān)鍵詞:嵌入式系統(tǒng);內(nèi)存管理;雙向鏈表
中圖分類號:TP309 ? ? ? ?文獻標識碼:A
文章編號:1009-3044(2019)15-0281-02
1 引言
在嵌入式系統(tǒng)軟件開發(fā)過程中,由于嵌入式系統(tǒng)的特殊性,系統(tǒng)擁有的資源是十分有限的,但是又要滿足各個子系統(tǒng)功能的使用要求,這就要求對嵌入式系統(tǒng)資源進行最高效、合理的使用[3]。內(nèi)存管理是嵌入式系統(tǒng)軟件開發(fā)中非常重要的子功能,由于資源的限制,內(nèi)存資源是否被合理利用并且高效利用已經(jīng)成為嵌入式軟件開發(fā)的核心[4]。
在一般的靜態(tài)內(nèi)存管理中,嵌入式系統(tǒng)軟件可以使用操作系統(tǒng)封裝的內(nèi)存分配和內(nèi)存釋放接口,而其管理是經(jīng)過操作系統(tǒng)進行的,并且內(nèi)存空間的首地址和大小一般也是固定的。開發(fā)者只可看到內(nèi)存空間是否分配成功、是否釋放成功和是否引起內(nèi)存泄露等[5]。動態(tài)分配是根據(jù)實時需要,將一段動態(tài)給定的地址空間作為一個內(nèi)存池,根據(jù)內(nèi)存池的首地址和長度對內(nèi)存空間進行合理化的動態(tài)分段管理和使用。因此,內(nèi)存動態(tài)管理方式相比內(nèi)存靜態(tài)管理方式更加靈活,內(nèi)存使用率也更高。本文提出一種機載嵌入式系統(tǒng)內(nèi)存動態(tài)管理方式,使用雙向鏈表方式動態(tài)對內(nèi)存空間進行管理和操控,在內(nèi)存空間資源有限的前提下高效利用空間資源,并且極大程度減少內(nèi)存泄露的發(fā)生[6]。
2 動態(tài)內(nèi)存管理方案與設(shè)計
2.1 內(nèi)存池初始化
一般情況下,動態(tài)內(nèi)存管理的方式是在系統(tǒng)需要時,實時的根據(jù)給定的一段可用物理內(nèi)存空間的首地址和內(nèi)存空間長度,通過一定的方式將物理內(nèi)存空間轉(zhuǎn)化成軟件可直接操控的空間,提供給軟件各個功能模塊使用[7]。本文提出的內(nèi)存管理方式,首先根據(jù)提供的可用內(nèi)存首地址和內(nèi)存長度,根據(jù)字節(jié)對齊將這段內(nèi)存空間分配為一個分段連續(xù)的內(nèi)存池空間,可看作連續(xù)的內(nèi)存塊組。根據(jù)多少字節(jié)對齊可以由需求動態(tài)決定,對齊的字節(jié)個數(shù)保持和每次需要申請空間的大小一致,或可將需要的內(nèi)存空間大小整除,可將內(nèi)存充分使用,避免內(nèi)存碎片的產(chǎn)生。使用過程中也可以根據(jù)需要針對同一個內(nèi)存空間,使用不同的對齊字節(jié)分配多個子內(nèi)存池來滿足使用。
定義一個雙向鏈表結(jié)構(gòu)體變量指針,作為第一個結(jié)構(gòu)體變量,其中的內(nèi)存空間變量指針指向內(nèi)存池內(nèi)存塊組的第一個內(nèi)存塊,結(jié)構(gòu)體變量中保存了直接前驅(qū)和直接后繼兩個結(jié)構(gòu)體的指針(初始都為NULL),以及當前結(jié)構(gòu)體變量指針所指內(nèi)存塊和當前結(jié)構(gòu)體的直接后繼結(jié)構(gòu)體變量所指向內(nèi)存塊之間的內(nèi)存塊使用與否的標志變量(初始為未使用)以及內(nèi)存塊個數(shù)(初始為所有內(nèi)存塊) 。
2.2 給定大小內(nèi)存空間申請
當需要申請內(nèi)存空間時,首先找到當前結(jié)構(gòu)體變量,并計算需申請的內(nèi)存空間需要使用多少個內(nèi)存塊。先判斷當前結(jié)構(gòu)體變量指向的內(nèi)存中剩余的內(nèi)存塊個數(shù)是否大于需要申請的內(nèi)存空間所使用的內(nèi)存塊個數(shù)并且剩余內(nèi)存塊組使用標志位是否為未使用,然后申請一個新的雙向鏈表結(jié)構(gòu)體變量指針,新結(jié)構(gòu)體變量指針的內(nèi)存空間變量指針指向的地址空間為當前的結(jié)構(gòu)體變量指向的內(nèi)存塊地址向后偏移一段長度,此長度為需要申請的內(nèi)存空間所使用的內(nèi)存塊個數(shù),其直接前驅(qū)指針指向當前的結(jié)構(gòu)體變量,直接后繼指針指向當前結(jié)構(gòu)體變量的直接后繼結(jié)構(gòu)體變量,其當前可用內(nèi)存塊個數(shù)為當前結(jié)構(gòu)體變量中保存的內(nèi)存塊個數(shù)減去需要申請的內(nèi)存空間所使用的內(nèi)存塊個數(shù)后余下的內(nèi)存塊個數(shù),并將當前結(jié)構(gòu)體變量中的內(nèi)存塊使用與否標記為使用,將新的結(jié)構(gòu)體變量中的內(nèi)存塊使用與否標記為未使用。最后將當前結(jié)構(gòu)體變量指向的內(nèi)存塊地址傳出給外部使用,并將新的結(jié)構(gòu)體變量當作當前的結(jié)構(gòu)體變量;若剛開始當前結(jié)構(gòu)體變量指向的內(nèi)存塊使用標志為已使用或可用內(nèi)存塊個數(shù)不夠,則繼續(xù)尋找下一個結(jié)構(gòu)體變量,若為空則當前結(jié)構(gòu)體變量取值為指向第一個內(nèi)存塊的結(jié)構(gòu)體變量,實現(xiàn)內(nèi)存空間的環(huán)形尋址使用。
作為舉例,根據(jù)系統(tǒng)需要對齊的字節(jié)長度為a。假設(shè)當前分配好的內(nèi)存池大小為a*n,總共可分配n個內(nèi)存塊。現(xiàn)在已申請3a大小內(nèi)存塊基礎(chǔ)上需再申請2a大小的內(nèi)存塊,具體流程圖如圖1所示,灰色內(nèi)存塊標注已使用。
若后面需申請的內(nèi)存空間大小所需內(nèi)存塊個數(shù)超過n-5,當前結(jié)構(gòu)體變量指針中標記的剩余內(nèi)存塊個數(shù)不夠,且當前結(jié)構(gòu)體變量指針的直接后繼指針為空,則將第一個結(jié)構(gòu)體變量First標記為當前結(jié)構(gòu)體變量指針,繼續(xù)之前操作。
2.3 釋放給定地址內(nèi)存塊
當需要釋放內(nèi)存空間時,首先根據(jù)內(nèi)存地址尋找其在內(nèi)存池中所對應(yīng)的內(nèi)存塊,并找到保存這個內(nèi)存塊首地址的目標結(jié)構(gòu)體變量。將目標結(jié)構(gòu)體變量使用標志設(shè)為未使用,然后取目標結(jié)構(gòu)體變量的直接前驅(qū)和直接后繼兩個結(jié)構(gòu)體變量指針,若前后兩個結(jié)構(gòu)體變量所指向的內(nèi)存塊組均不為空,并且使用標志位和目標結(jié)構(gòu)體指向的內(nèi)存塊一致,則將此三個結(jié)構(gòu)體變量合成為一個,并將其中的所有內(nèi)存塊合并為一整個內(nèi)存塊,指針指向此內(nèi)存塊的結(jié)構(gòu)體變量設(shè)置為當前結(jié)構(gòu)體變量;若目標結(jié)構(gòu)體變量的直接前驅(qū)或直接后繼結(jié)構(gòu)體變量所指向內(nèi)存塊組的使用標志位和目標結(jié)構(gòu)體變量不一致,則不對使用標志位不一致的結(jié)構(gòu)體變量以及對應(yīng)的內(nèi)存塊組進行合并。作為舉例,要釋放第二個結(jié)構(gòu)體變量指針指向的內(nèi)存塊組,內(nèi)存塊組有兩個內(nèi)存塊,如圖2所示:
首先將目標結(jié)構(gòu)體變量標記的內(nèi)存塊組使用標記設(shè)置為未使用,然后修改其直接前驅(qū)和直接后繼的頭尾指針,將目標結(jié)構(gòu)體變量中包含的可用內(nèi)存塊組個數(shù)疊加到其直接前驅(qū)結(jié)構(gòu)體變量中,將目標結(jié)構(gòu)體變量和其直接前驅(qū)結(jié)構(gòu)體變量合稱為一個結(jié)構(gòu)體變量,描述為當前結(jié)構(gòu)體變量。最后用同樣方式,將當前結(jié)構(gòu)體變量和直接后繼結(jié)構(gòu)體變量合成為一個結(jié)構(gòu)體變量,描述為當前結(jié)構(gòu)體變量。具體流程圖如圖3所示:
釋放指定內(nèi)存塊,就是將指向其地址的結(jié)構(gòu)體變量和其直接前驅(qū)以及直接后繼三個結(jié)構(gòu)體變量進行合成,疊加其可用內(nèi)存塊個數(shù),并釋放其所指內(nèi)存塊組。
3 結(jié)束語
本文提出了一種基于嵌入式系統(tǒng)的動態(tài)內(nèi)存管理方式,該方法可以實現(xiàn)內(nèi)存的動態(tài)管理,和內(nèi)存高效、高速申請和釋放,通過實時傳入的空間地址、空間大小以及實時需要,動態(tài)申請分配內(nèi)存池,并且使用雙向鏈表結(jié)構(gòu)體指針來動態(tài)管理內(nèi)存池,保證了內(nèi)存空間使用的合理性以及連續(xù)性,很大程度上避免了內(nèi)存碎片的產(chǎn)生,并且保證了內(nèi)存管理功能模塊的穩(wěn)定性和整個嵌入式軟件的安全性。經(jīng)過測試本文提出的動態(tài)內(nèi)存管理方式是一種高效、綜合性能好內(nèi)存管理方式,可作為一種內(nèi)存管理方案滿足嵌入式系統(tǒng)軟件使用要求。
參考文獻:
[1] 田令平.嵌入式操作系統(tǒng)內(nèi)存管理研究[J].電腦知識與技術(shù), 2006(4):169-171.
[2] 符麗枚,陳世航.嵌入式軟件運行內(nèi)存余量測試方法[J].自動化應(yīng)用,2014(11):6-8.
[3] 陸小雙,帥建梅,吳慶響.一種新的面向?qū)ο蟪绦虻膬?nèi)存管理器[J].計算機工程,2012,38(9):21-23.
[4] 吳文峰.嵌入式實時系統(tǒng)動態(tài)內(nèi)存分配管理器的設(shè)計與實現(xiàn)[D].重慶:重慶大學(xué),2013.
[5] 楊磊,汪仁煌,劉洪江,黃穎怡.使用Visual Leak Detector檢測C/C++程序內(nèi)存泄漏[J].電腦與電信,2008(07).
[6] 陳力軍,魏永軍,迮超.一種內(nèi)存管理系統(tǒng)及其分配方法[P].中國專利號:01139150.2,2001.
[7] 魏海濤,姜昱明,李建武等.內(nèi)存管理機制的高效實現(xiàn)研究[J].計算機工程與設(shè)計,2009,30(16):3708-3712.
【通聯(lián)編輯:代影】