日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

在应用程序中使用虚拟内存——Windows核心编程学习手札之十五

發(fā)布時間:2025/4/16 windows 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在应用程序中使用虚拟内存——Windows核心编程学习手札之十五 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在應(yīng)用程序中使用虛擬內(nèi)存

——Windows核心編程學(xué)習(xí)手札之十五

Windows提供了3種進行內(nèi)存管理的方法:

1)? 虛擬內(nèi)存,最適合用來管理大量對象或結(jié)構(gòu)數(shù)組;

2)? 內(nèi)存映射文件,最適合用來管理大型數(shù)據(jù)流(通常來自文件)以及在單個計算機上運行的多個進程之間共享數(shù)據(jù);

3)? 內(nèi)存堆棧,最適合用來管理大量的小對象;

用于管理虛擬內(nèi)存的函數(shù)可以用來直接保留一個地址空間區(qū)域,將物理存儲器(來自頁文件)提交給該區(qū)域,并且可以設(shè)置你自己的保護屬性。

通過調(diào)用VirtualAlloc函數(shù),可以在進程的地址空間中保留一個區(qū)域:

PVOID VirtualAlloc(

???????????????? PVOID pvAddress,

???????????????? SIZE_T dwSize,

???????????????? DWORD fdwAllocationType,

???????????????? DWORD fdwProtect);

第一個參數(shù)pvAddress包含一個內(nèi)存地址,用于設(shè)定想讓系統(tǒng)將地址空間保留在什么地址,多數(shù)情況下,該參數(shù)傳遞NULL,用于告訴VirtualAlloc,保存一個空間地址區(qū)域的記錄的系統(tǒng)應(yīng)該將區(qū)域保留在它認為合適的任何地方。系統(tǒng)可以從進程的地址空間的任何位置來保留一個區(qū)域,因為不能保證系統(tǒng)可以從地址空間的底部向上或從上面向底部來分配各個區(qū)域,使用MEM_TOP_DOWN標(biāo)志來說明該分配方式。

分配內(nèi)存時,操作系統(tǒng)尋找一個大小滿足需要的內(nèi)存塊,并返回內(nèi)存塊的地址,由于每個進程有自己的地址空間,可以設(shè)定一個基本內(nèi)存地址,在這個地址上讓操作系統(tǒng)保留地址空間區(qū)域。例如,將一個從50MB開始的區(qū)域保留在進程的地址空間中,傳遞pvAddress52428800(50*1024*1024),如果該內(nèi)存地址有一個足夠大的空閑區(qū)域滿足你的要求,那系統(tǒng)就保留這個區(qū)域并返回地址,如果在特定的地址上不存在空閑區(qū)域,或者空閑區(qū)域不夠大,那系統(tǒng)就不滿足需求,VirtualAlloc函數(shù)返回NULL。注意,為pvAddress參數(shù)傳遞的任何地址必須始終位于進程的用戶方式分區(qū)中,否則對VirtualAlloc函數(shù)的調(diào)用就會失敗,導(dǎo)致其返回NULL。地址空間區(qū)域總是按照分配粒度的邊界來保留(迄今為止所有的Windows環(huán)境下都是64KB),因此,如果試圖在進程地址空間中保留一個從19668992(300*65356+8192)這個地址開始的區(qū)域,系統(tǒng)就會將這個地址保留為64KB的倍數(shù),即19660800(300*65356)開始的區(qū)域。如果VirtualAlloc函數(shù)滿足了需求,就返回保留區(qū)域的基地址,如果傳遞一個指定的地址作為VirtualAllocpvAddress參數(shù),那么該返回值與傳遞給VirtualAlloc的值相同,并取為64KB的整數(shù)倍。

VirtualAlloc函數(shù)的第二個參數(shù)是dwSize,用于設(shè)定想保留的區(qū)域大小(以字節(jié)為單位),系統(tǒng)保留的區(qū)域必須是CPU頁面大小的倍數(shù),如試圖保留一個跨越62KB的區(qū)域,結(jié)果就會在使用4KB/8KB16KB頁面的計算機上產(chǎn)生一個跨越64KB的區(qū)域。

VirtualAlloc函數(shù)的第三個參數(shù)是fdwAllocationType,告訴系統(tǒng)想保留一個區(qū)域還是提交物理存儲器(VirtualAlloc函數(shù)也可以用來提交物理存儲器),若要保留一個地址空間區(qū)域,傳遞MEM_RESERVE標(biāo)識符作為fdwAllocationType參數(shù)的值。如果保留區(qū)域預(yù)計在很長時間內(nèi)不會被釋放,那可以在盡可能高的內(nèi)存地址上保留該區(qū)域,這樣,該區(qū)域就不會從進程地址空間的中間位置上進行保留,因此這個位置可能導(dǎo)致區(qū)域分成碎片,如果想讓系統(tǒng)在最高內(nèi)存地址上保留一個區(qū)域,需為pvAddress參數(shù)和fdwAllocationType參數(shù)傳遞NULL,還必須逐位使用ORMEM_TOP_DOWN標(biāo)志和MEM_RESERVE標(biāo)志連接起來。

VirtualAlloca最后一個參數(shù)是fdwProtect,用于指明應(yīng)該賦予該地址空間區(qū)域的保護屬性。與該區(qū)域相關(guān)聯(lián)的保護屬性對映射到該區(qū)域的已提交內(nèi)存沒有影響,無論賦予區(qū)域的保護屬性是社呢,如果沒有提交任何物理存儲器,那訪問該范圍中的內(nèi)存地址的任何企圖都將導(dǎo)致該線程引發(fā)一個訪問違規(guī)。

當(dāng)保留一個區(qū)域后,必須將物理存儲器提交給該區(qū)域,然后才能訪問該區(qū)域中包含的內(nèi)存地址,系統(tǒng)從它的頁文件中將已提交的物理存儲器分配給一個區(qū)域,物理存儲器總是按頁面邊界和頁面大小的塊來提交的。若要提交物理存儲器,須再次調(diào)用VirtualAlloc函數(shù),設(shè)置參數(shù)fdwAllocationTypeMEM_COMMIT,傳遞的頁面保護屬性一般與調(diào)用VirtualAlloc來保留區(qū)域時使用的保護屬性相同(大多數(shù)情況下是PAGE_READWRITE)。在已保留的區(qū)域中,須告訴VirtualAlloc函數(shù),要將物理存儲器提交到那里以及提交多大物理存儲空間,實現(xiàn)這一點,需要在pvAddress參數(shù)中設(shè)定需要的內(nèi)存地址,并在dwSize參數(shù)上設(shè)定物理存儲器的大小。

提交物理存儲器的例子:應(yīng)用程序在X86CPU上運行,保留了一個從地址5242880開始的512KB區(qū)域,現(xiàn)在將物理存儲器提交給已保留區(qū)域的6KB部分,從2KB的地方開始,直到已保留區(qū)域的地址空間。可調(diào)用帶有MEM_COMMIT標(biāo)志的VirtualAlloc函數(shù):

VirtualAlloc((PVOID)(5242880+(2*1024)),6*1024,MEM_COMMIT,PAGE_READWRITE);

例子中,系統(tǒng)必須提交8KB的物理存儲器,地址范圍從52428805251071(5242880+8KB-1),這兩個提交的頁面都擁有PAGE_READWRITE保護屬性,保護屬性在整個頁面單位內(nèi)生效,同一個內(nèi)存頁面的不同部分不能使用不同的保護屬性,但在不同區(qū)域中的一個頁面可以使用兩種以上保護屬性。

若要回收映射到一個區(qū)域的物理存儲器,或者釋放這個地址空間區(qū)域,可調(diào)用VirtualFree函數(shù):

BOOL VirtualFree(

?????? ????????LPVOID pvAddress,

?????????????? SIZE_T dwSize,

?????????????? DWORD fdwFreeType);

當(dāng)進程不再訪問區(qū)域中的物理存儲器,可以釋放整個保留的區(qū)域和所有提交給該區(qū)域的物理存儲器,方法是一次調(diào)用VirtualFree函數(shù)。pvAddress是釋放區(qū)域的基地址,與該區(qū)域被保留時VirtualAlloc函數(shù)返回的地址相同,系統(tǒng)知道在特定內(nèi)存地址上的區(qū)域大小,因此dwSize參數(shù)可以為零,實際,該參數(shù)必須傳遞零,否則調(diào)用VirtualFree失敗,對最后一個參數(shù)fdwFreeType,必須傳遞MEM_RELEASE,以告訴系統(tǒng)將所有映射的物理存儲器提給該區(qū)域并釋放該區(qū)域,當(dāng)釋放一個區(qū)域時,必須釋放該區(qū)域保留的所有地址空間。如不想保留128KB的區(qū)域,不能只釋放64KB。當(dāng)想要從一個區(qū)域回收某些物理存儲器,但是卻不釋放該區(qū)域,設(shè)置參數(shù)fdwFreeTypeMEM_DECOMMIT標(biāo)志。回收時也按照頁面的分配粒度來進行,設(shè)定一個頁面中間的一個內(nèi)存地址就可以回收整個頁面,如果pvAddress+dwSize的值位于一個頁面的中間,那包含該地址的整個頁面將被回收,因此,位于pvAddresspvAddress+dwSize范圍內(nèi)的所有頁面均被回收。

?

總結(jié)

以上是生活随笔為你收集整理的在应用程序中使用虚拟内存——Windows核心编程学习手札之十五的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。