windows下的記憶體管理

來源:互聯網
上載者:User

1.Windows的記憶體結構

Windows系統中的每個進程都被賦予它自己的虛擬位址空間。對於32位進程來說,這個地址空間是4GB,因為32位指標可以擁有從0x00000000至0xFFFFFFFF之間的任何一個值。對於64位進程來說,則這個空間是16EB。由於每個進程可以接收它自己的私人的地址空間,因此當進程中的一個線程正在運行時,該線程也只能訪問只屬於它的進程的記憶體。屬於所有其他進程的記憶體則隱藏著,並且不能被訪問。

每個進程的虛擬位址空間都要劃分成各個分區,地址空間的分區時根據作業系統的基本實現來進行的,不同的windows核心,其分區也略有不同。下面以32位windows 2000 (x86和alpha處理器)

另外,如果使用者想把使用者方式分區擴大到3GB,則在x86的windows 2000 advanced server版本和windows 2000 data center版本中可以加入/3GB開關到BOOT.INI檔案中。使用/3GB開關後,將減少系統能夠建立的線程、堆棧和其他資源的數量。此外,系統最多使用16GB的RAM,而通常情況下可以使用64GB的RAM。因為核心方式中沒有足夠的虛擬空間來管理更多的RAM。

2.地址空間中的地區

當進程被建立並被賦予它的地址空間時,該可用空間的主體是閒置,未分配的。若要使用該地址空間的各個部分,必須要調用virtualAlloc 函數來分配它裡邊的各個地區。對每一個地址空間的地區進行分配的操作稱為保留(reserve)

   當你保留地址空間的一個地區時,該地區必須是系統的頁面大小的倍數,而且分配邊界必須從一個分配粒度開始。例如x86的頁面大小為4KB,分配粒度為64KB。

 若要使用已保留的地址空間地區,則必須分配實體儲存體器,然後將該實體儲存體器映射到已保留的地址空間地區。這個過程叫提交實體儲存體器。也調用VirtualAlloc函數,但和前面保留的輸入參數有所區別,可以自己查此函數。當然使用者也可以在保留地址空間的同時提交實體儲存體器。

 在較老的作業系統中,實體儲存體器被視為電腦所有的RAM的容量。如果電腦有16M的RAM,則載入和啟動並執行應用程式最多可以使用16M的RAM。今天的作業系統則使得磁碟空間看上去像記憶體一樣。磁碟上的檔案通常稱為頁檔案,它包含了可以供所有進程使用的虛擬記憶體。(使用者可以在“我的電腦->屬性->進階”裡面查看虛擬記憶體的頁檔案資訊)

這樣,當一個應用程式通過調用VirtrualAlloc函數,將實體儲存體器提交給地址空間的一個地區時,地址空間實際上是從硬碟上的一個檔案中進行分配的。

 當使用者進程中的一個線程試圖訪問進程的地址空間中的一個資料區塊的時候。一般會發生兩種情況:

1. 線程試圖訪問的資料是在RAM中,則cpu只需要將虛擬位址映射到記憶體的物理地址中,然後執行需要的訪問。

2. 資料不在RAM中,而是放在頁檔案的某個地方。這時候,訪問引起頁面失效,cpu將通知作業系統,作業系統就從RAM中尋找一個空白頁,如果找不到空白頁,則必須釋放一個頁。如果該頁面沒有被修改過,則可以直接釋放,否則必須先把此頁面從RAM拷貝到頁面分頁檔,然後系統進入該頁檔案,找出需要訪問的資料,並將資料載入到閒置記憶體頁面。然後,作業系統更新它的用於指明資料的虛擬記憶體地址現在已經映射到RAM中的相應的實體儲存體器地址中的表。

3. Windows的記憶體管理方法

 windows提供了3種方法來進行記憶體管理:

l         虛擬記憶體,最適合用來管理大型物件或者結構數組

l         記憶體對應檔,最適合用來管理大型資料流(通常來自檔案)以及在單個電腦上運行多個進程之間共用資料。

l         記憶體堆棧,最適合用來管理大量的小對象。

3.1 虛擬記憶體

 虛擬記憶體的使用主要有以下幾個步驟:

1. 在地址空間保留一個地區,調用函數VirtualAlloc

2. 在保留地區中的提交實體儲存體器,當保留一個地區後,必須將實體儲存體器提交給該地區,然後才能訪問該地區中包含的記憶體位址。系統從它的頁檔案中將已提交的實體儲存體器分配給一個地區。仍舊調用函數VirtualAlloc具體參數設定可以見msdn,當然,使用者也可以一次性地進行操作保留地區和提交實體儲存體器。

3. 回收虛擬記憶體和釋放地址空間地區,調用VirtualFree函數,並且,如果要釋放一個地區,必須釋放該地區保留地所有地址空間。當然使用者也可以只回收實體儲存體器而不釋放地區,仍舊調用VirtualFree函數,但參數傳入不同。

3.2 記憶體對應檔

 與虛擬記憶體一樣,記憶體對應檔可以用來保留一個地址空間的地區,並將實體儲存體器提交給該地區。他們之間的區別是,實體儲存體器來自一個已經位於磁碟上的檔案,而不是系統的頁檔案。一旦該檔案被映射,就可以訪問它,就像整個檔案被載入到了記憶體一樣。

   記憶體對應檔一般用於3個不同的目的:

1.       系統使用記憶體對應檔,以便載入和執行.exe和DLL檔案。這可以大大節省頁檔案空間和應用程式啟動運行所需的時間

2.       可以使用記憶體對應檔來訪問磁碟上的資料文家愛女。這使你可以不比對檔案執行i/o操作,並且可以不必對檔案內容進行緩衝

3.       可以使用記憶體對應檔,使同一台電腦上啟動並執行多個進程能夠相互之間共用資料。

若要使用記憶體對應檔,必須執行下列操作步驟:

1) 建立或開啟一個檔案核心對象,該對象用於標識磁碟上你想用作記憶體對應檔的檔案 (CreateFile函數)

2) 建立一個檔案對應核心對象,告訴系統該檔案的大小和你打算如何訪問該檔案

(CreateFileMapping函數)

3) 讓系統將檔案對應物件的全部或一部分映射到你的地址空間

(MapViewOfFile函數,要求檔案的位移是分配粒度的倍數)

當完成對記憶體對應檔的使用時,必須執行下面的這些步驟將它清除:

4)告訴系統從你的進程的地址空間中撤銷檔案對應核心對象的映象

(UnmapViewOfFile函數)

5)關閉檔案對應核心對象

(CloseHandle函數,第2)步建立的對象)

6)關閉檔案核心對象

(CloseHandle函數,第1)步建立的對象)

利用記憶體對應檔,還可以實現進程之間的資料共用。資料共用的方法是通過讓兩個或多個進程映射同一個檔案對應物件的視圖,這也意味著他們將共用實體儲存體器的同一個頁面。另外,使用者也可以建立由系統的頁檔案支援的記憶體對應檔,而不是由專用硬碟檔案支援的記憶體對應檔。這樣,就不需要調用CreateFile函數,只需要給CreateFileMapping的Hfile參數傳遞INVALID_HANDLE_VALUE,並傳遞一個以0結尾的字串作為pszName參數。別的進程就可以用CreateFileMapping或者OpenFilemapping函數。

 3.3 堆棧

 堆棧可以用來分配許多較小的資料區塊,例如對連結資料表和連結樹進行管理等。堆棧的優點是,可以不考慮分配粒度和頁面邊界之類的問題。堆棧的缺點是,分配和釋放記憶體塊的速度比其他機制要慢,並且無法直接控制實體儲存體器的提交和回收。

   當進程初始化時,系統在進程的地址空間中建立一個堆棧。該堆棧為進程的預設堆棧。按照預設設定,該堆棧的地址空間地區的大小是1MB。系統可以擴大進程的預設堆棧。由於進程的預設堆棧可以供許多windows函數調用,因此對預設堆棧的訪問是按順序進行的。也就是,系統必須保證在規定的時間內,每次只有一個線程能分配和釋放預設堆棧中的記憶體塊 。當然,使用者也可以在進程的地址空間中建立一些輔助堆棧。

 堆棧的一些操作函數如下(具體可以查msdn):

1.建立堆棧    HeapCreate

2. 從堆棧中分配記憶體塊 HeapAlloc

3. 改變記憶體塊的大小 HeapReAlloc

4. 釋放記憶體塊 HeapFree

5. 撤銷堆棧   HeapDestroy

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.