虛擬記憶體實現的硬體基礎是分頁機制,關於分頁機制本文再此不做介紹。虛擬記憶體實現的另外乙個重要基礎是區域性性原理。區域性性是指程式總是趨向於使用最近使用過的資料和指令,也就是說程式執行時所訪問的儲存器位址分布是相對集中的。區域性性原理是應用虛擬記憶體提公升效能的主要原因,也是虛擬記憶體卻別與記憶體對映檔案的本質。
記憶體對映檔案虛擬性並不是由於區域性性,而是使程序虛擬位址空間的某個區域建立對映磁碟檔案的全部或部分內容,通過該區域可以直接對被對映的磁碟檔案進行訪問,而不必執行檔案i/o操作也無需對檔案內容進行緩衝處理。
記憶體對映檔案
1.載入並執行exe和dll.
2.訪問磁碟的資料檔案,而不必執行檔案i/o操作。
3.不同程序之間共享資料。
對映到記憶體的可執行檔案和dll
1.呼叫createprocess,確定可執行檔案的位置
2.系統建立乙個新的程序核心物件『
3.系統為新程序建立乙個新的位址空間
4.系統預定足夠大的位址空間容納exe檔案,
5.系統對位址空間標註,表明該區域是來自磁碟的exe檔案,而不是系統的頁交換檔案。
當exe檔案對映到程序的位址空間後,後呼叫loadlibrary函式載入dll.同時dll和上面步驟4,5一樣。
在exe或dll檔案中,**段通常在資料段前面。使用編譯器編譯的時候
.bss 未經初始化的資料
.data 已初始化的資料
.text exe或dll 的**
此外可以使用編譯器自定義段
#pragma data_seg ("dllsharedsection ")
int i = 0; //必須要初始化
#prama data_seg()
鏈結器的工作
僅定義乙個資料段還不能達到共享資料的目的,還要告訴編譯器該段的屬性,有三 種方法可以實現該目的(其效果是相同的),
一種方法是在.def檔案中加入如下語句:setctions dllsharedsection read write shared
另一種方法是在專案設定的鏈結選項(project setting --〉link)中加入如下語句:
/section:dllsharedsection,rws
還有一種就是使用指令:
#pragma comment(linker,"/section:.dllsharedsection,rws")
檔案對映核心物件
1.建立檔案核心物件,呼叫createfile.目的是為了告訴系統檔案對映的物理儲存器的位置。
handle
createfile(
lpctstr
lpfilename,
//普通檔名或者裝置檔名
dword
dwdesiredaccess,
//訪問模式(寫/讀) generc_write geberic_read
dword
dwsharemode, //共享模式 file_share_erad file_share_write
如果是零表示不共享,其他程序無法開啟同一檔案
lpsecurity_attributes lpsecurityattributes,
//指向安全屬性的指標 null
dword
dwcreationdisposition, //如何建立
open_existing create_always
dword
dwflagsandattributes, //檔案屬性
file_attribute_normal
handle
htemplatefile //用於複製檔案控制代碼
通常這個引數設定為null,為空表示不使用模板
);
handle
_in_handle hfile,
_in_opt_lpsecurity_attributes lpattributes,
_in_dword flprotect,
_in_dword dwmaximumsizehigh,
_in_dword dwmaximumsizelow,
_in_opt_lpctstr lpname);
hfile:long,指定欲在其中建立對映的乙個檔案控制代碼。0xffffffff(-1,即invalid_handle_value)表示在頁面檔案中建立乙個可共享的檔案對映,表明建立的檔案對映物件的物理儲存器不是磁碟的檔案,而是系統從頁交換檔案中調撥物理儲存器。即在磁碟c的pagefile.sys檔案,因此不需要再呼叫createfile函式。
flprotect:可以是page_readwrite page_readonly page_write 等 但這些引數必須跟createfile的變數dwdesiredaccess對應起來。
dwmaximumsizehigh:long,檔案對映的最大長度的高32位。在小於4g ,該值為0
dwmaximumsizelow:long,檔案對映的最大長度的低32位。
如果想要用當前檔案的大小建立乙個檔案對映物件,只要傳0給兩個引數就可以。
如果傳入的是page_readwrite,如果檔案大小比指定的要小,則會增大檔案的大小。
如果使用的是page_readonly或page_writecopy,指定的大小不能大於檔案的大小。
lpname:以0為終止符的字串,這個名詞可以實現不同的程序間共享記憶體。
3.將檔案的資料對映到程序的位址空間,呼叫mapviewoffile
);
dwfileoffsethigh 表示檔案對映起始偏移的高32位. 一般是0
dwfileoffsetlow 表示檔案對映起始偏移的低32位.(64kb對齊不是必須的) 一般是0
dwnumberofbytes 指定對映檔案的位元組數. 如果是0 ,表示檔案都對映到位址空間中。同時該變數也意味著只對映部分檔案對映檔案到程序的位址空間。
如果成功,則返回對映視**件的開始位址值
該函式是核心物件,符合跨程序共享資料的特性。
作用就是:
為檔案的資料預訂一塊位址空間區域並將檔案的資料作為物理儲存器調撥給區域。
4.從程序的位址空間撤銷檔案資料的對映,呼叫unmapviewoffile,釋放程序位址空間。
bool winapi unmapviewoffile(_in_lpcvoid lpbaseaddress);
lpbaseaddress long,指定要解除對映的乙個檔案對映的基準位址。這個位址是早先用mapviewoffile函式獲得的
在呼叫mapviewoffile後,必須呼叫
unmapviewoffile進行撤銷對映。因為如果不呼叫unmapviewoffile,那麼載呼叫
mapviewoffile的時候,系統會在程序的位址空間預訂一塊新的區域,不會釋放先前預訂的。
5.關閉檔案對映物件,呼叫closehandle
6.關閉檔案物件,呼叫closehandle
特點:1,系統允許同一檔案的資料對映到多程序的多個檢視。檢視的資料保持一致性,如果乙個檢視修改內容,其他檢視也更新。
2.乙個程序呼叫mapviewoffile,系統在程序位址空間預訂的區域,其他程序是看不到這個檢視的。另乙個程序呼叫mapviewoffile,是在第二個程序的位址空間預訂另乙個區域。
3.此外,兩個程序呼叫mapviewoffile的返回值基位址很可能不一樣。
《Windows核心程式設計》筆記 虛擬記憶體 記憶體
1 32位系統支援的最大位址空間4gb 2 32 為何是4gb而不是4gb呢?因為最小儲存單元是byte 這個是由系統決定,有些系統可能不一樣 由上可知 記憶體條容量大於4gb時,32位系統可能會浪費記憶體。記憶體條小於4gb時,32位系統支援的最大定址空間由記憶體條容量決定。2 虛擬記憶體是為了擴...
Delphi下深入Windows核心程式設計
目錄 第1章 dll與資料共享 1.1 關於dll 1.1.1 dll的結構 1.1.2 dll資料作用範圍 1.2 記憶體映像 1.2.1 建立映像檔案 1.2.2 開啟映像檔案 1.2.3 對映到本程序中 1.2.4 關閉記憶體對映 1.2.5 兩個exe檔案共享記憶體資料塊 1.2.6 兩個d...
Windows核心程式設計 記憶體對映檔案(2)
2.對映到記憶體的資料檔案 這種方法最大的優點是讓系統為我們處理所有與檔案快取有關的操作,我們不必關心分配記憶體 把檔案中的資料載入記憶體,把資料 寫回檔案 以及釋放記憶體等操作,不過如果 操作過程被打斷,比如斷電,資料可能被破壞。要使用記憶體對映檔案,需執行以下步驟 1 建立或開啟乙個檔案核心物件...