內(nèi)存碎片處理技術(shù)
發(fā)布時間:2008/5/27 0:00:00 訪問次數(shù):469
    
    內(nèi)存碎片是一個很棘手的問題。如何分配內(nèi)存決定著內(nèi)存碎片是否會、何時會、如何會成為一個問題。
    
    即使在系統(tǒng)中事實上仍然有許多空閑內(nèi)存時,內(nèi)存碎片還會最終導致出現(xiàn)內(nèi)存用完的情況。一個不斷產(chǎn)生內(nèi)存碎片的系統(tǒng),不管產(chǎn)生的內(nèi)存碎片多么小,只要時間足夠長,就會將內(nèi)存用完。這種情況在許多嵌入式系統(tǒng)中,特別是在高可用性系統(tǒng)中是不可接受的。有些軟件環(huán)境,如 ose 實時操作系統(tǒng)已經(jīng)備有避免內(nèi)存碎片的良好工具,但個別程序員做出的選擇仍然會對最終結(jié)果形成影響。
    “碎片的內(nèi)存”描述一個系統(tǒng)中所有不可用的空閑內(nèi)存。這些資源之所以仍然未被使用,是因為負責分配內(nèi)存的分配器使這些內(nèi)存無法使用。這一問題通常都會發(fā)生,原因在于空閑內(nèi)存以小而不連續(xù)方式出現(xiàn)在不同的位置。由于分配方法決定內(nèi)存碎片是否是一個問題,因此內(nèi)存分配器在保證空閑資源可用性方面扮演著重要的角色。
    
    編譯時間與運行時間
    在許多情況下都會出現(xiàn)內(nèi)存分配問題。程序員可以通過編譯程序和鏈接程序,為結(jié)構(gòu)、并集、數(shù)組和標量(用作局部變量、靜態(tài)變量或全局變量)方面的數(shù)據(jù)分配內(nèi)存,程序員還可以在運行時間使用諸如 malloc()調(diào)用命令動態(tài)地分配內(nèi)存。當用編譯程序和鏈接程序完成內(nèi)存分配功能時,就不會出現(xiàn)內(nèi)存碎片,因為編譯程序了解數(shù)據(jù)壽命。掌握可供使用的數(shù)據(jù)壽命,好處在于可以使數(shù)據(jù)以后進先出的方式疊加起來。這樣就可以使內(nèi)存分配程序工作效率更高,而不會出現(xiàn)內(nèi)存碎片。一般來說,運行時間內(nèi)的內(nèi)存分配是不可疊加的。內(nèi)存分配在時間上是獨立的,從而使得碎片問題難以解決。
    
    
    
    圖 1,內(nèi)存碎片的幾種形式。
    
    內(nèi)存分配程序浪費內(nèi)存的基本方式有三種:即額外開銷、內(nèi)部碎片以及外部碎片(圖 1)。內(nèi)存分配程序需要存儲一些描述其分配狀態(tài)的數(shù)據(jù)。這些存儲的信息包括任何一個空閑內(nèi)存塊的位置、大小和所有權(quán),以及其它內(nèi)部狀態(tài)詳情。一般來說,一個運行時間分配程序存放這些額外信息最好的地方是它管理的內(nèi)存。內(nèi)存分配程序需要遵循一些基本的內(nèi)存分配規(guī)則。例如,所有的內(nèi)存分配必須起始于可被 4、8 或 16 整除(視處理器體系結(jié)構(gòu)而定)的地址。內(nèi)存分配程序把僅僅預定大小的內(nèi)存塊分配給客戶,可能還有其它原因。當某個客戶請求一個 43 字節(jié)的內(nèi)存塊時,它可能會獲得 44字節(jié)、48字節(jié) 甚至更多的字節(jié)。由所需大小四舍五入而產(chǎn)生的多余空間就叫內(nèi)部碎片。
    外部碎片的產(chǎn)生是當已分配內(nèi)存塊之間出現(xiàn)未被使用的差額時,就會產(chǎn)生外部碎片。例如,一個應用程序分配三個連續(xù)的內(nèi)存塊,然后使中間的一個內(nèi)存塊空閑。內(nèi)存分配程序可以重新使用中間內(nèi)存塊供將來進行分配,但不太可能分配的塊正好與全部空閑內(nèi)存一樣大。倘若在運行期間,內(nèi)存分配程序不改變其實現(xiàn)法與四舍五入策略,則額外開銷和內(nèi)部碎片在整個系統(tǒng)壽命期間保持不變。雖然額外開銷和內(nèi)部碎片會浪費內(nèi)存,因此是不可取的,但外部碎片才是嵌入系統(tǒng)開發(fā)人員真正的敵人,造成系統(tǒng)失效的正是分配問題。
    定義內(nèi)存碎片的方法有幾種,其中最常用的是:
    
    
    
    這一方法適用于外部碎片,但可以修改這一公式使之包括內(nèi)部碎片,辦法是把內(nèi)部碎片加入到分母中。內(nèi)存碎片是一個介于 0 和 1 之間的分數(shù)。一個碎片為 1(100%)的系統(tǒng)就是把內(nèi)存全用完了。如果所有空閑內(nèi)存都在一個內(nèi)存塊(最大內(nèi)存塊)中,碎片為 0%。當所有空閑內(nèi)存的四分之一在最大內(nèi)存塊中時,碎片為 75%。例子如下:一個系統(tǒng)有 5m 字節(jié)的空閑內(nèi)存,當它可用來分配的最大內(nèi)存塊為 50 k 字節(jié)時,其內(nèi)存碎片為99%。這個 99%內(nèi)存碎片實例來自開發(fā)嵌入式軟實時系統(tǒng)期間出現(xiàn)的一種真實情況。當這種碎片程度發(fā)生一秒后,系統(tǒng)就崩潰了。該系統(tǒng)在碎片率達到 99% 之前,已經(jīng)進行了約兩周的連續(xù)現(xiàn)場測試。這種情況是如何發(fā)生的?為什么會發(fā)現(xiàn)得如此晚?當然,系統(tǒng)都經(jīng)過測試,但測試很少超過兩個小時。交付前的最后壓力測試持續(xù)了一個周末。在這樣短的測試周期內(nèi)未必會產(chǎn)生內(nèi)存碎片的后果,所以就發(fā)生了內(nèi)存碎片需要多長時間才會達到臨界值,這一問題很難回答。對某些應用來說,在某些情況下,系統(tǒng)會在用完內(nèi)存前達到一種穩(wěn)定狀態(tài)。而對
    
    內(nèi)存碎片是一個很棘手的問題。如何分配內(nèi)存決定著內(nèi)存碎片是否會、何時會、如何會成為一個問題。
    
    即使在系統(tǒng)中事實上仍然有許多空閑內(nèi)存時,內(nèi)存碎片還會最終導致出現(xiàn)內(nèi)存用完的情況。一個不斷產(chǎn)生內(nèi)存碎片的系統(tǒng),不管產(chǎn)生的內(nèi)存碎片多么小,只要時間足夠長,就會將內(nèi)存用完。這種情況在許多嵌入式系統(tǒng)中,特別是在高可用性系統(tǒng)中是不可接受的。有些軟件環(huán)境,如 ose 實時操作系統(tǒng)已經(jīng)備有避免內(nèi)存碎片的良好工具,但個別程序員做出的選擇仍然會對最終結(jié)果形成影響。
    “碎片的內(nèi)存”描述一個系統(tǒng)中所有不可用的空閑內(nèi)存。這些資源之所以仍然未被使用,是因為負責分配內(nèi)存的分配器使這些內(nèi)存無法使用。這一問題通常都會發(fā)生,原因在于空閑內(nèi)存以小而不連續(xù)方式出現(xiàn)在不同的位置。由于分配方法決定內(nèi)存碎片是否是一個問題,因此內(nèi)存分配器在保證空閑資源可用性方面扮演著重要的角色。
    
    編譯時間與運行時間
    在許多情況下都會出現(xiàn)內(nèi)存分配問題。程序員可以通過編譯程序和鏈接程序,為結(jié)構(gòu)、并集、數(shù)組和標量(用作局部變量、靜態(tài)變量或全局變量)方面的數(shù)據(jù)分配內(nèi)存,程序員還可以在運行時間使用諸如 malloc()調(diào)用命令動態(tài)地分配內(nèi)存。當用編譯程序和鏈接程序完成內(nèi)存分配功能時,就不會出現(xiàn)內(nèi)存碎片,因為編譯程序了解數(shù)據(jù)壽命。掌握可供使用的數(shù)據(jù)壽命,好處在于可以使數(shù)據(jù)以后進先出的方式疊加起來。這樣就可以使內(nèi)存分配程序工作效率更高,而不會出現(xiàn)內(nèi)存碎片。一般來說,運行時間內(nèi)的內(nèi)存分配是不可疊加的。內(nèi)存分配在時間上是獨立的,從而使得碎片問題難以解決。
    
    
    
    圖 1,內(nèi)存碎片的幾種形式。
    
    內(nèi)存分配程序浪費內(nèi)存的基本方式有三種:即額外開銷、內(nèi)部碎片以及外部碎片(圖 1)。內(nèi)存分配程序需要存儲一些描述其分配狀態(tài)的數(shù)據(jù)。這些存儲的信息包括任何一個空閑內(nèi)存塊的位置、大小和所有權(quán),以及其它內(nèi)部狀態(tài)詳情。一般來說,一個運行時間分配程序存放這些額外信息最好的地方是它管理的內(nèi)存。內(nèi)存分配程序需要遵循一些基本的內(nèi)存分配規(guī)則。例如,所有的內(nèi)存分配必須起始于可被 4、8 或 16 整除(視處理器體系結(jié)構(gòu)而定)的地址。內(nèi)存分配程序把僅僅預定大小的內(nèi)存塊分配給客戶,可能還有其它原因。當某個客戶請求一個 43 字節(jié)的內(nèi)存塊時,它可能會獲得 44字節(jié)、48字節(jié) 甚至更多的字節(jié)。由所需大小四舍五入而產(chǎn)生的多余空間就叫內(nèi)部碎片。
    外部碎片的產(chǎn)生是當已分配內(nèi)存塊之間出現(xiàn)未被使用的差額時,就會產(chǎn)生外部碎片。例如,一個應用程序分配三個連續(xù)的內(nèi)存塊,然后使中間的一個內(nèi)存塊空閑。內(nèi)存分配程序可以重新使用中間內(nèi)存塊供將來進行分配,但不太可能分配的塊正好與全部空閑內(nèi)存一樣大。倘若在運行期間,內(nèi)存分配程序不改變其實現(xiàn)法與四舍五入策略,則額外開銷和內(nèi)部碎片在整個系統(tǒng)壽命期間保持不變。雖然額外開銷和內(nèi)部碎片會浪費內(nèi)存,因此是不可取的,但外部碎片才是嵌入系統(tǒng)開發(fā)人員真正的敵人,造成系統(tǒng)失效的正是分配問題。
    定義內(nèi)存碎片的方法有幾種,其中最常用的是:
    
    
    
    這一方法適用于外部碎片,但可以修改這一公式使之包括內(nèi)部碎片,辦法是把內(nèi)部碎片加入到分母中。內(nèi)存碎片是一個介于 0 和 1 之間的分數(shù)。一個碎片為 1(100%)的系統(tǒng)就是把內(nèi)存全用完了。如果所有空閑內(nèi)存都在一個內(nèi)存塊(最大內(nèi)存塊)中,碎片為 0%。當所有空閑內(nèi)存的四分之一在最大內(nèi)存塊中時,碎片為 75%。例子如下:一個系統(tǒng)有 5m 字節(jié)的空閑內(nèi)存,當它可用來分配的最大內(nèi)存塊為 50 k 字節(jié)時,其內(nèi)存碎片為99%。這個 99%內(nèi)存碎片實例來自開發(fā)嵌入式軟實時系統(tǒng)期間出現(xiàn)的一種真實情況。當這種碎片程度發(fā)生一秒后,系統(tǒng)就崩潰了。該系統(tǒng)在碎片率達到 99% 之前,已經(jīng)進行了約兩周的連續(xù)現(xiàn)場測試。這種情況是如何發(fā)生的?為什么會發(fā)現(xiàn)得如此晚?當然,系統(tǒng)都經(jīng)過測試,但測試很少超過兩個小時。交付前的最后壓力測試持續(xù)了一個周末。在這樣短的測試周期內(nèi)未必會產(chǎn)生內(nèi)存碎片的后果,所以就發(fā)生了內(nèi)存碎片需要多長時間才會達到臨界值,這一問題很難回答。對某些應用來說,在某些情況下,系統(tǒng)會在用完內(nèi)存前達到一種穩(wěn)定狀態(tài)。而對
熱門點擊
- 用存儲器映射的方法實現(xiàn)片外FLASH的擦寫
- SST89E/V58RD2和SST89E/V
- 消磁器確保所有磁介質(zhì)擦除干凈
- 基于VxWorks的FLASH存儲器實時存取
- 邊界掃描SRAM簇板級互連測試研究
- 基于C8051F320 USB接口的數(shù)據(jù)采集
- 利用RLDRAM II存儲器提高網(wǎng)絡(luò)設(shè)備性能
- 幾種新型非易失性存儲器
- 為DDR-SDRAM度身定造高效功率管理芯片
- VB環(huán)境下對雙端口RAM物理讀寫的實現(xiàn)
推薦技術(shù)資料
- 循線機器人是機器人入門和
- 循線機器人是機器人入門和比賽最常用的控制方式,E48S... [詳細]