註:本文只涉及到Windows 2000,而不涉及Win98。對於Win98,記憶體的分區與2000的有著截然的差異。
1.進程的虛擬位址空間
在32位應用程式中,進程的虛擬位址空間有著4GB的記憶體可用。因為32位的指標可以表示0X00000000至0XFFFFFFFF的地址。
每個進程中的線程可以訪問自己進程中記憶體。屬於其它進程的記憶體相對於線程來說是隱藏的,不能被訪問!
還有一段記憶體是隱藏的,那就是作業系統所佔用的記憶體。線程不能訪問作業系統的資料。但是這對於win98是個例外。
虛擬記憶體空間並不是實際的記憶體中地址。進程A中的虛擬位址0X12345678所映射的實際記憶體位址並不是進程B中的虛擬位址0X12345678所映射的實際記憶體,雖然他們的虛擬位址的值都一樣。
所以,在Win32中,實際記憶體是被映射的!
另外,並不是所有4GB的虛擬位址空間都可以被訪問資料,確切的說,要看虛似記憶體有沒有被映射,如果是,則可以訪問 ,如果不是,則出現訪問資料違規操作。
2.虛擬記憶體中的分區
分區是為了把一些不同的資料分門別類出來,放在不同的資料區內。那有哪些類別呢?
(1)NULL指標區:0X00000000-0X0000FFFF
就是一些為NULL的指標所存放的地區,它的地址空間大小為64K。
線程讀取這64KB的資料是屬於違規訪問的,所以,我們明白了為什麼對於C++要做NULL的指標檢查,而不檢查有時就會出現違規訪問,就像下面代碼所示:int* pnSomeInteger = (int*) malloc(sizeof(int));
*pnSomeInteger = 5;
如果以上記憶體配置不成功,則malloc返回NULL,然後下面操作這個指標就會出現違規。
(2)使用者方式:0X00010000-0X7FFEFFFF
這個地方是放置進程私人代碼,資料的地方,另外的進程是無法對這個進程中這段記憶體的資料進行操作。這樣一來,應用程式就不太可能被其它程式所破壞,使系統更加健壯。
這段記憶體也是我們程式可以使用的記憶體地區。他的大小是不到2GB。剩下來的2GB是空給核心地址空間的。
(3)64KB進入區:0X7FFF00000-0X7FFFFFFF
又是線程所不能訪問的地區,為什麼建立這塊地區,書上說的是這樣的:M i c r o s o f t之所以保留該分區,是因為這樣做將使得M i c r o s o f t能夠更加容易地實現作業系統。當將記憶體塊的地址和它的長度傳遞給Wi n d o w s函數時,該函數將在執行它的操作之前使記憶體塊生效。
有點不明白?是嗎?
(4)核心方式分區:0X80000000-0XFFFFFFFF
存放作業系統的代碼,用於線程調度,記憶體管理,檔案系統支援,網路支援和所有裝置的驅動程式。
駐留在這兒的資料可被所有的進程分享。