![]() |
學校地址:湖南省 長沙市 雨花區 車站南路紅花坡路口 |
![]() |
學校地址:湖南省 長沙市 雨花區 車站南路紅花坡路口 |
近幾天,我在開發一款嵌入式移動產品項目上遇到了一點麻煩。這個應用是arm9內核和WinCE平臺,這幾天我一直被糾纏在一個內存問題,程序吃內存很厲害,跑一段時間后,內存占用就接近了,出現所謂的假死機。
看任務管理器里面的程序內存使用一直都很正常,但整個系統的內存卻在被緩慢的侵蝕,但就是看不出來是程序哪一部份使用了過多的內存。反復的查程序,也沒發現內存泄漏,需要不斷的修改內存分配策略,很頭疼。
1.WinCE是如何分配內存?
(1)WinCE內存環境
在PC上增加物理內存是很方便的,插上內存條后只要自檢程序識別,桌面操作系統就能夠支持,而在基于WinCE的產品上就沒那么簡單了。嵌入式設備與桌面PC的一個顯著不同是它的應用程序中通常需要直接訪問某一段物理內存,這在驅動程序中對物理內存的訪問尤為重要。尤其是像arm體系結構下,I/O端口也被映射成某一個物理內存地址。而且與桌面版本Windows相比,WinCE也提供相對簡單的物理內存訪問方式,無論是驅動程序還是應用程序都可以通過API訪問某一段物理內存。
一般來說,運行一個WinCE需要ROM(只讀存儲器)和RAM(隨機存儲器)。但在WinCE系統中,ROM和RAM的使用還是稍微有些不同于個人電腦環境。RAM在WinCE 系統中被分為兩個區域:第一個是程序存儲區(Program Memory),也叫做系統堆(System Heap),程序存儲區有點像個人電腦中的RAM,它為正在運行的應用程序保存堆和棧的內容。第二個是對象存儲區(Object Store),它有點像一個永久的虛擬RAM磁盤。不同于PC上的虛擬RAM磁盤,對象存儲區保留存儲的文件甚至可以在系統被關閉以后。
在WinCE系統中,存儲在ROM的程序能以現場執行(Execute in Place,XIP)的方式運行。換句話說,程序可以直接從ROM中執行而不必先加載到RAM中再執行。這種能力對嵌入式系統來說,具有兩個方面的巨大優勢,一是代碼直接從ROM中執行意味著程序代碼不會占據更有價值的RAM;二是程序在執行前也不必先復制到RAM中,這樣就只需要很少的時間來啟動一個應用程序。而不在ROM中的但是被含在對象存儲區或閃存卡中的程序將不能以現場方式執行,它們將被復制到RAM中再執行。
(2)虛擬內存
電腦中所有運行的程序都需要經過內存執行,如果執行的程序很大或很多,就會導致內存消耗殆盡。為了解決這個問題,Windows運用了虛擬內存技術,以緩解內存的緊張。和大多數操作系統一樣,WinCE也實現按需調頁的虛擬內存機制。WinCE是32位的操作系統,支持4GB的虛擬地址空間。系統調用虛擬內存API來為其它類型內存分配內存,括堆和棧。WinCE虛擬內存頁可以處在三種狀態:自由(free),保留(reserved),或被提交(committed)。
WinCE提供兩種虛擬地址映射方法,分別為靜態映射和動態映射,靜態映射的虛擬地址空間只能由內核訪問,而動態映射的地址空間可以由用戶模式的應用程序訪問。WinCE系統使用微處理器的內存管理單元(MMU)來處理虛擬地址和物理地址間的實時轉換。意思是說:一旦WinCE系統的MMU開始工作,CPU就不再直接訪問物理內存了,對于運行在x86和arm系列CPU上的CE內核來說,必須先確立物理內存地址和虛擬內存地址的映射關系。
這種關系是在一個名為OEMAddressTable的表中定義的,屬于靜態映射方法。因此,在一個虛擬內存系統中,應用程序主要處理這個虛擬的地址空間,并不涉及到由硬件管理的物理內存,應用程序使用虛擬內存不需要知道實際物理內存的位置,只要有內存可用就行。
2. WinCE與桌面WINDOWS在內存方面的區別
(1)Win32 API 接口之間的區別
WinCE實現了Windows XP中可用到的幾乎全部的Win32內存管理API。WinCE支持虛擬內存(virtual memory)分配,本地(local)和分離(separate)的堆(heaps),甚至還有(memory-mapped files)內存映射文件。雖然 WinCE 支持幾乎每個Win32 內存管理函數,但是開發人員應當永遠不要忘記 WinCE 是與 Windows XP 完全不同的操作系統,這些內存管理API的實現WinCE 具有不同的要求和不同的實現方式。
像Windows XP一樣,WinCE支持一個帶有應用程序間內存保護功能的32位地址空間,但是WinCE是被設計來應用于不同場合,所以它底層的內存結構不同于Windows XP。例如,WinCE不支持Win32 內存API的全局堆(global heap)。因此,開發人員應該熟悉 Win CE 與 Windows 桌面版本之間的細微差異,在設計應用程序或診斷問題時知道 WinCE 如何實現Win32 兼容性是一件非常重要的事情。
(2)存儲結構區別
WinCE實現了一個和其他Win32操作系統類似的分頁式虛擬內存系統。在WinCE中,一頁的大小可以從1024字節到4096字節,基于微處理器的不同而不同。這和Windows XP不同,Windows 頁面尺寸是Intel微處理器所支持的4096字節。
WinCE 通過改變每頁的保護來保護程序內存,而不是分配給每一程序不同地址空間。存儲在ROM中的程序組在WinCE下當地執行,所以嵌入式系統的設計者能夠只占用很少的RAM用于堆棧存儲的需要。而且為了進一步的增加應用程序軟件的性能,WinCE采用按需求將內存分頁,操作系統僅僅需要解壓縮并且裝入基于RAM的一小部分程序準備執行。因此,ROM和基于RAM的程序的靈活性與速度意味著基于WinCE的設備能夠被構造成多種內存結構形式。
(3)低內存環境的區別
WinCE定義了內存門檻(Memory thresholds),它有四種內存狀態:Normal, Limited, Low和Critical,這些狀態的劃分主要取決于當前可用的內存大小。WinCE監視系統自由的RAM,并對越來越少的RAM作出響應。當很少內存可用時,WinCE發送WM_HIBERNATE消息,接下來會限制可能的內存分配。當系統運行需要更多的內存,而又不能滿足的情況下,shell會自動關閉該應用程序。
例如,OS首先向非活動狀態的程序發送此消息,請求它們在不破壞各自內在狀態情況下盡量釋放多的內存,比如釋放GDI對象;如果沒有可用的物理RAM,需要棧空間的線程就會被掛起;如果在給定的一小段時間內,這個內存需求不能得到響應,就會彈出系統異常。簡單說是:當系統運行在一個低RAM環境中,應用程序將調整并 小化它們的內存使用,如果當系統需要更多內存時,外殼(shell)會自動關閉這些程序。因此,管理WinCE運行在低內存系統中的程序的方法有很多種,但必須要小心應用,否則容易造成程序掛起或被關閉。
|