基于嵌入式設(shè)備瀏覽器內(nèi)存管理策略研究
摘要:為了解決嵌入式設(shè)備中內(nèi)存頻繁分配和釋放所引起的內(nèi)存碎片以及瀏覽器正常運(yùn)行難問(wèn)題,提出具有垃圾回收機(jī)制的可動(dòng)態(tài)增長(zhǎng)池式分配數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)和具有Compaction機(jī)制的Vector分配方法;在嵌入式環(huán)境系統(tǒng)設(shè)計(jì)時(shí),采用可回收動(dòng)態(tài)增長(zhǎng)池式分配策略,系統(tǒng)無(wú)需預(yù)潮內(nèi)存大小,而且可以循環(huán)使用池內(nèi)空間;Compaction機(jī)制的Vector分配方法可以移動(dòng)“在用”對(duì)象和“廢棄”對(duì)象調(diào)整內(nèi)存占用,減少碎片。實(shí)驗(yàn)設(shè)計(jì)中應(yīng)用上述策略,驗(yàn)證了該內(nèi)存管理效率比系統(tǒng)級(jí)效率要高,嵌入式設(shè)備中打開(kāi)網(wǎng)頁(yè)文件越大,體現(xiàn)出來(lái)的效率更高。
關(guān)鍵詞:嵌入式設(shè)備;瀏覽器;池式分配;位圖;對(duì)象表
0 引言
在嵌入式系統(tǒng)中,由于設(shè)備性能限制系統(tǒng)總的可分配內(nèi)存相對(duì)較小,而在嵌入式平臺(tái)上瀏覽器正常運(yùn)行所需內(nèi)存一般都比較大,并且內(nèi)存分配和釋放操作也比較頻繁,例如,IPTV EPG界面上顯示各類菜單按鈕、鏈接以及為用戶提供動(dòng)態(tài)和靜態(tài)的多媒體內(nèi)容時(shí),往往EPG頁(yè)面中存在著各種長(zhǎng)短不一節(jié)目導(dǎo)航提示信息、各種表單、導(dǎo)航按鈕以及圖片等,對(duì)于這些要顯示的對(duì)象需要通過(guò)數(shù)個(gè)矩形數(shù)據(jù)結(jié)構(gòu)來(lái)表示它們。在界面排版過(guò)程中,隨著上、下文的改變,會(huì)進(jìn)行頻繁的分配釋放,例如把圖片插入到網(wǎng)頁(yè)的時(shí)候,網(wǎng)頁(yè)會(huì)把一個(gè)局部區(qū)域內(nèi)的顯示對(duì)象釋放然后重新生成,從內(nèi)存管理角度來(lái)看,這導(dǎo)致了頻繁的內(nèi)存分配和釋放。為了保證瀏覽器Browser的正常運(yùn)行和減小內(nèi)部碎片,本文在分析和研究μCLinux嵌入式操作系統(tǒng)內(nèi)存管理基礎(chǔ)之上,提出運(yùn)行在嵌入式設(shè)備上瀏覽器的內(nèi)存管理策略,該策略主要針對(duì)瀏覽器中固定大小結(jié)構(gòu)的頻繁分配和釋放,比如各種box,采用池式分配的方式(Pooled Allocation)來(lái)管理固定大小結(jié)構(gòu)的分配和釋放;對(duì)于可變大小結(jié)構(gòu)的分配和釋放,比如字符串,采用Vector進(jìn)行分配和釋放。
1 μCLinux內(nèi)存管理分析
μCLinux是主流嵌入式Linux系統(tǒng)之一,其設(shè)計(jì)的目標(biāo)平臺(tái)是那些不具有內(nèi)存管理單元(MMU)的微處理芯片。μCLinux對(duì)標(biāo)準(zhǔn)Linux修改最大的部分在于內(nèi)存管理部分,而瀏覽器內(nèi)存管理是在一塊已分配的內(nèi)存上進(jìn)行苒組織內(nèi)存的使用方式,把這塊已分配的內(nèi)存當(dāng)作物理內(nèi)存來(lái)使用。因此μCLinux的內(nèi)存管理思想對(duì)于本文設(shè)計(jì)嵌入式設(shè)備瀏覽器內(nèi)存管理有較好參考意義。
1.1 μCLinux內(nèi)存管理數(shù)據(jù)結(jié)構(gòu)
μCLinux取消了標(biāo)準(zhǔn)Linux的VMA結(jié)構(gòu)(該結(jié)構(gòu)建立在虛擬內(nèi)存之上),每個(gè)進(jìn)程維護(hù)自己的內(nèi)存地址空間的方法是在它的mm_DataStruet中維護(hù)了一個(gè)此進(jìn)程所使用的內(nèi)存塊的鏈表。一個(gè)進(jìn)程可以擁有任意多個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊用mm_Rblock_DataStruct類型的數(shù)據(jù)結(jié)構(gòu)描述其起始地址、長(zhǎng)度以及當(dāng)前被使用的次數(shù)。每個(gè)內(nèi)存塊由mMap()的調(diào)用來(lái)建立。
每個(gè)進(jìn)程維護(hù)了一個(gè)mm_DataStruct結(jié)構(gòu)(如圖1所示)用來(lái)管理它所擁有的內(nèi)存空間。tblock是管理所有這個(gè)進(jìn)程所用到的內(nèi)存區(qū)域塊的鏈表表頭。mm_Tbloek_DataStruet是管理mm_Rblock_DataStruct的鏈表結(jié)構(gòu),rblock指向當(dāng)前位置的鏈表項(xiàng),next是指向下一個(gè)位置的鏈表項(xiàng)。mm_Rblock_DataStruct結(jié)構(gòu)是用來(lái)管理內(nèi)存塊的數(shù)據(jù)結(jié)構(gòu),size指明kblock所指向的內(nèi)存區(qū)域的大小,ref_count記錄了這個(gè)內(nèi)存空間的用戶個(gè)數(shù),kbloek是指向這個(gè)內(nèi)存塊空間起始位置的指針。
1.2 μCLinux物理空間管理
雖然μCLinux中對(duì)內(nèi)存地址的操作都是直接對(duì)物理內(nèi)存進(jìn)行的,但是仍然需要使用Linux中對(duì)物理頁(yè)幀的管理數(shù)據(jù)結(jié)構(gòu),μCLinux對(duì)物理空間管理主要有以下幾個(gè)方面:
(1)物理內(nèi)存以頁(yè)幀為單位,頁(yè)幀的長(zhǎng)度固定為4 KB,在內(nèi)核中使用page結(jié)構(gòu)來(lái)表示每個(gè)物理頁(yè)幀;
(2)所有的page結(jié)構(gòu)形成一個(gè)mem_map表,mem_map表在系統(tǒng)初始化時(shí)由free_area_init()函數(shù)創(chuàng)建;
(3)在物理內(nèi)存低端的bitmap表以位圖方式記錄了所有物理內(nèi)存的空閑狀況,它也是在系統(tǒng)初始化時(shí)由free_area_init()函數(shù)創(chuàng)建,bitmap表分割NR_MEM_LISTS組,對(duì)第i組初始化時(shí)設(shè)定長(zhǎng)度為(end_mem_start_mem)/PAGE_SIZE/2(i+3),每位表示連續(xù)2i個(gè)頁(yè)幀的空狀況,置位為1表示其中一頁(yè)或幾頁(yè)已被占用;
(4)用free_area數(shù)組記錄空閑的物理頁(yè)幀,free_area數(shù)組由NR_MEM_LISTS個(gè)free_area_struct結(jié)構(gòu)類型的數(shù)組元素構(gòu)成,每個(gè)元素均作為一條空閑塊鏈表的表頭,連續(xù)2i個(gè)空閑頁(yè)幀則掛到free_area數(shù)組的第i項(xiàng)后面,free_area當(dāng)前空閑頁(yè)面?zhèn)€數(shù)要大于系統(tǒng)中硬性規(guī)定的必須保留的空閑頁(yè)面的個(gè)數(shù)(5或者低于5的某個(gè)數(shù)值),如果不足規(guī)定的空閑頁(yè)面,則調(diào)用try_to_free_page()函數(shù)嘗試增加系統(tǒng)中的空閑頁(yè)面的數(shù)量;
(5)Linux采用buddy算法分配空閑塊。
2 嵌入式設(shè)備瀏覽器內(nèi)存管理策略
應(yīng)用程序?yàn)g覽器內(nèi)存管理是在一塊已分配的內(nèi)存上進(jìn)行再組織內(nèi)存的使用方式,它不會(huì)涉及操作系統(tǒng)的內(nèi)存管理,但是可以借鑒操作系統(tǒng)的各種內(nèi)存管理方法,使對(duì)應(yīng)用程序級(jí)的內(nèi)存管理更高效。首先系統(tǒng)獲得一塊固定大小的內(nèi)存,然后把這塊內(nèi)存按照功能進(jìn)行固定分區(qū),圖2是Brow ser內(nèi)存管理各分區(qū)的布局。把從系統(tǒng)獲得的內(nèi)存分為4個(gè)區(qū):第一個(gè)區(qū)是Static Section,大小為20 KB,這個(gè)區(qū)主要用于保存全局性數(shù)據(jù)結(jié)構(gòu)GlobalCtlVar,50 Word大小的索引緩存(Indi-ces Buffer)和Pool Linked List。第二個(gè)區(qū)是String Map Section是一個(gè)對(duì)象表,大小為20 KB,用于存入數(shù)組結(jié)構(gòu)StrMap的數(shù)組,預(yù)定義數(shù)組大小為1 000,String Map功能之一類似于bitmap,用于管理空閑的數(shù)據(jù)塊。第三個(gè)區(qū)是Reserve Section(保留區(qū)),大小是20 KB。第四個(gè)區(qū)是Available Section,真正分配給用戶的內(nèi)存從這個(gè)區(qū)取出,有關(guān)pool的分配從上到下,有關(guān)Vector的分配從下到上。
評(píng)論