WinCE內(nèi)存管理報(bào)告
1. Windows CE支持虛擬內(nèi)存動(dòng)態(tài)分配(virtual memory allocation),局部和單獨(dú)的堆空間(Local and separate heaps),甚至內(nèi)存映射文件(memory_mapped files,memory mapping simplifies file access. Instead of using a system-maintained pointer to write to the file, you can write directly to memory.)
2. Windows CE環(huán)境下ROM和RAM的使用和我們平時(shí)的PC機(jī)有所不同。RAM被分為 兩個(gè)區(qū)域:程序區(qū)(proram memory),也叫系統(tǒng)堆(system heap),和對(duì)象存儲(chǔ)(object store)。
l 對(duì)象存儲(chǔ)可以被看作類似于一個(gè)永久的虛擬RAM磁盤。在Pocket PC上,當(dāng)我們關(guān)閉顯示屏后,系統(tǒng)實(shí)際上并沒(méi)有真正斷電,而是進(jìn)入一個(gè)低功耗的睡眠狀態(tài)(由主電池來(lái)供電)。當(dāng)我們按下后面的Reset按鈕后,Windows CE內(nèi)核在RAM中尋找最近一次創(chuàng)建的對(duì)象存儲(chǔ),如果找到的話,就是用這個(gè)對(duì)象存儲(chǔ)重新啟動(dòng)。
l RAM的另一個(gè)區(qū)域是程序區(qū)。這個(gè)區(qū)域就像PC機(jī)的RAM一樣。它存放所運(yùn)行程序的堆和棧的空間。對(duì)象存儲(chǔ)和程序區(qū)的界限是可移動(dòng)的。在低內(nèi)存的情況下,系統(tǒng)會(huì)請(qǐng)求用戶把部分可用的存儲(chǔ)對(duì)象空間提供給運(yùn)行程序使用,以滿足程序運(yùn)行的RAM需要。
u PC機(jī)上,ROM用來(lái)存儲(chǔ)BIOS,通常是64-128K。在WindowCE系統(tǒng)中,ROM用來(lái)存儲(chǔ)整個(gè)操作系統(tǒng)以及和OS綁定的應(yīng)用程序,大小可以4-32M不等。因此,WinCE下的ROM就像一個(gè)很小的只讀硬盤一樣。
u 在WinCE OS中,ROM_based程序可以被指定位就地執(zhí)行(Excute in Place)。也就是說(shuō),它們直接從ROM中執(zhí)行而不是先載入RAM然后再執(zhí)行。這樣不僅可以節(jié)省寶貴的Ram資源,而且程序啟動(dòng)更快。不在ROM中的程序(在對(duì)象存儲(chǔ)空間里的或者是在Flash內(nèi)存中的)不能原地執(zhí)行。
3. 虛擬內(nèi)存。OS使用微處理的內(nèi)存管理單元實(shí)時(shí)地把虛擬地址轉(zhuǎn)換到物理地址。
u 分頁(yè)內(nèi)存(Paged Memory)。在WinCE OS下,一頁(yè)是1K或者4K,取決于微處理芯片。Intel 的ARM,一頁(yè)是4K。
u 虛擬頁(yè)面有三種狀態(tài):未用的(free),保留的(reserved)和占用的(committed)。一個(gè)free的頁(yè)面,顧名思義就是可以被分配的。一個(gè)reserved頁(yè)面就是已經(jīng)被預(yù)定的,所以他的虛擬地址空間不能再分配給操作系統(tǒng)和這個(gè)進(jìn)程的另一個(gè)線程。它的地址還未映射到物理空間。一個(gè)committed頁(yè)就是已經(jīng)被一個(gè)程序保留了并且已經(jīng)直接映射到了一個(gè)物理地址空間。
4.WinCE地址空間
u 為所有的應(yīng)用程序?qū)崿F(xiàn)單個(gè)的2GB的虛擬地址,但是每個(gè)應(yīng)用程序的內(nèi)存空間都是受保護(hù)的,以保證其他應(yīng)用程序不能訪問(wèn)。從最低的虛擬地址空間開(kāi)始分為33個(gè)slot,每個(gè)slot32M。每個(gè)slot被分配為當(dāng)前運(yùn)行的進(jìn)程。Slot 0中存放的當(dāng)前激活的進(jìn)程。當(dāng)winCE在進(jìn)程間切換時(shí),它就重新映射地址空間,把老進(jìn)程移出,新進(jìn)程移進(jìn)slot 0。這個(gè)任務(wù)是通過(guò)操作微處理器的頁(yè)轉(zhuǎn)換表來(lái)迅速完成的。
u 33個(gè)slot以上地址區(qū)域是為OS和映射內(nèi)存映射文件保留的。和windows XP一樣,winCE也保留了最低的64K地址空間,任何進(jìn)程都不能訪問(wèn)。
5.查詢系統(tǒng)內(nèi)存。
u GetSystemInfo(LPSYSTEM_INFO)
u GlobalMemoryStatus(LPMEMORYSTATUS)(paging files are not supported under windows CE)
6.各種內(nèi)存分配方式
u 首先是Virtualxxxx函數(shù),用來(lái)預(yù)留,提交和釋放虛擬內(nèi)存頁(yè)。然后是堆API。堆使用該應(yīng)用程序管理的保留內(nèi)存空間區(qū)域。堆有兩種:缺省的局部堆和獨(dú)立堆。堆API下來(lái)是靜態(tài)數(shù)據(jù),這些數(shù)據(jù)塊由編譯器定義并且在載入時(shí)自動(dòng)分配。最后是棧,它存放應(yīng)用程序中每個(gè)函數(shù)的局部變量。
u wince不支持全局堆。因此全局堆API,wince都不支持。
u 在wince中減少內(nèi)存使用的關(guān)鍵是選擇恰當(dāng)?shù)膬?nèi)存分配策略。
6.1 虛擬內(nèi)存
它是內(nèi)存類型中最基本的。系統(tǒng)可以調(diào)用虛擬內(nèi)存API來(lái)為其他內(nèi)存類型分配空間,比如堆,棧。VirtualAlloc,VirtualFree,VirtualResize函數(shù)直接在這個(gè)應(yīng)用程序的虛擬內(nèi)存空間里操作虛擬內(nèi)存頁(yè)。可以使用這些函數(shù)預(yù)留,提交和是否物理內(nèi)存。(以頁(yè)為單位的,舍入到頁(yè)的界限)
6.2 堆
顯然,以頁(yè)為單位分配內(nèi)存對(duì)于大多數(shù)程序是低效的。而堆就可以以字節(jié)為單位來(lái)申請(qǐng)和釋放內(nèi)存。粒度比虛擬內(nèi)存函數(shù)要?。ㄖ辽?字節(jié))。系統(tǒng)會(huì)隨著所運(yùn)行程序的需求自動(dòng)增長(zhǎng)堆的大小。當(dāng)堆中的一些塊被釋放后,系統(tǒng)檢查看是否整個(gè)頁(yè)都被釋放了,如果是的話,這個(gè)頁(yè)就被decommit。由于在一個(gè)堆上不斷地allocate和free,這個(gè)堆很可能被分割為一些碎片,或者有可能這個(gè)堆幾乎是空的,但是系統(tǒng)還是不能從這個(gè)堆中釋放 a page,除非它全空。
u Local Heap。每個(gè)應(yīng)用程序在啟動(dòng)時(shí)都會(huì)創(chuàng)建一個(gè)缺省的堆。可以使用LocalAlloc,LocalFree和LocalRealloc函數(shù)操作這個(gè)堆。
u Separate Heaps。為了避免把堆分割成很多碎片,如果在一段時(shí)間里需要一塊連續(xù)的塊空間的話,更好的方法是創(chuàng)建一個(gè)單獨(dú)的堆。實(shí)際申請(qǐng)空間時(shí)才映射物理地址空間,并不才創(chuàng)建時(shí)就保留或者提交任何內(nèi)存。Destroy這個(gè)堆時(shí)并不要求里面的數(shù)據(jù)塊都釋放了。
6.3棧
缺省一個(gè)??臻g最大是58K。當(dāng)??臻g逐漸變小時(shí),系統(tǒng)將進(jìn)入低內(nèi)存狀態(tài)。??臻g的最大值可以在鏈接時(shí)指定??梢灾付ǖ?M。注意:
u 缺省??臻g大小也是所有其他獨(dú)立線程棧的大小。
u 如果沒(méi)有可用的物理RAM,需要??臻g的線程就會(huì)被掛起。如果在給定的一小段時(shí)間內(nèi),這個(gè)內(nèi)存需求不能得到響應(yīng),就會(huì)彈出系統(tǒng)異常。在低內(nèi)存情況下不應(yīng)該嘗試使用大量的棧空間。
6.4 靜態(tài)數(shù)據(jù)
預(yù)定義內(nèi)存塊在程序載入時(shí)為它們自動(dòng)分配空間。這些塊中的數(shù)據(jù)包含了靜態(tài)申請(qǐng)的字符串,緩沖區(qū),和全局變量以及和這個(gè)應(yīng)用程序靜態(tài)鏈接的函數(shù)庫(kù)。Wince為一個(gè)應(yīng)用程序申請(qǐng)兩個(gè)RAM塊:一個(gè)用于存放Read/Write數(shù)據(jù),一個(gè)用于存放只讀數(shù)據(jù)。由于這些區(qū)域都是以頁(yè)為單位來(lái)分配內(nèi)存的,所以為了節(jié)省空間,盡量使靜態(tài)數(shù)據(jù)段接近但不能超過(guò)頁(yè)的范圍。如果在靜態(tài)數(shù)據(jù)段還有相當(dāng)空間,可以把本來(lái)動(dòng)態(tài)申請(qǐng)的一些緩沖區(qū)移到靜態(tài)數(shù)據(jù)區(qū)。有時(shí)根據(jù)具體情況可以把只讀數(shù)據(jù)區(qū)中的一些數(shù)據(jù)移到讀寫數(shù)據(jù)區(qū)。決定的方法是查看map文件。
7.在低內(nèi)存情況下WinCE如何處理應(yīng)用程序的內(nèi)存請(qǐng)求。
當(dāng)系統(tǒng)運(yùn)行需要更多的內(nèi)存,而又不能滿足的情況下,shell會(huì)自動(dòng)關(guān)閉該應(yīng)用程序。因此wince提供了一些方法來(lái)在所有正在運(yùn)行的程序間分配寶貴的內(nèi)存資源。
u WM_HIBERNATE消息。OS首先向非活動(dòng)狀態(tài)的程序發(fā)送此消息,請(qǐng)求它們?cè)诓黄茐母髯詢?nèi)在狀態(tài)情況下盡量釋放多的內(nèi)存,比如釋放GDI對(duì)象,緩沖數(shù)據(jù)等等。
u 內(nèi)存門檻(memory thresholds)。WinCE定義了四種內(nèi)存狀態(tài):normal, limited, low and critical。這些狀態(tài)的劃分主要取決于當(dāng)前可用的內(nèi)存大小。當(dāng)可用內(nèi)存很少時(shí),系統(tǒng)首先發(fā)送WM_HIBERNATE消息,然后限制內(nèi)存申請(qǐng)的請(qǐng)求。
評(píng)論