青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Programmer's Cookbook

{C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

windows核心編程--虛擬內存

Wi n d o w s提供了3種進行內存管理的方法,它們是:
虛擬內存,最適合用來管理大型對象或結構數組。

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

內存堆棧,最適合用來管理大量的小對象。


虛擬內存的狀態
Wi n d o w s函數G l o b a l M e m o r y S t a t u s可用于檢索關于當前內存狀態的動態信息:
VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);
如果希望應用程序在內存大于4 G B的計算機上運行,或者合計交換文件的大小大于4 G B,那么可以使用新的G l o b a l M e m o r y S t a t u s E x函數:
BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst);

確定地址空間的狀態
Wi n d o w s提供了一個函數,可以用來查詢地址空間中內存地址的某些信息(如大小,存儲器類型和保護屬性等)。
這個函數稱為Vi r t u a l Q u e r y:
DWORD VirtualQuery(
   LPCVOID pvAddress,
   PMEMORY_BASIC_INFORMATION pmbi,
   DWORD dwLength);
Wi n d o w s還提供了另一個函數,它使一個進程能夠查詢另一個進程的內存信息:
DWORD VirtualQueryEx(
   HANDLE hProcess,
   LPCVOID pvAddress,
   PMEMORY_BASIC_INFORMATION pmbi,
   DWORD dwLength);
這兩個函數基本相同,差別在于使用Vi r t u a l Q u e r y E x時,可以傳遞你想要查詢的地址空間信息的進程的句柄。調試程序和其他實用程序使用這個函數最多,幾乎所有的應用程序都只需要調用Vi r t u a l Q u e r y函數。
為了獲得完整的內存信息,我創建了一個函數,即V M Q u e r y:
BOOL VMQuery(
   HANDLE hProcess,
   PVOID pvAddress,
   PVMQUERY pVMQ);
系統信息

許多操作系統的值是根據主機而定的,比如頁面的大小,分配粒度的大小等。這些值決不應該用硬編碼的形式放入你的源代碼。相反,你始終都應該在進程初始化的時候檢索這些值,并在你的源代碼中使用檢索到的值。G e t S y s t e m I n f o函數將用于檢索與主機相關的值:

 

VOID GetSystemInfo(LPSYSTEM_INFO psinf);


必須傳遞S Y S T E M _ I N F O結構的地址給這個函數。這個函數將初始化所有的結構成員然后返回。下面是S Y S T E M _ I N F O數據結構的樣子。

 

typedef  struct  _SYSTEM_INFO
{
   union
   
{
      DWORD dwOemId;  
// Obsolete, do not use
       struct  
      
{
         WORD wProcessorArchitecture;
         WORD wReserved;
      }
;
   }
;
   DWORD     dwPageSize;
   LPVOID    lpMinimumApplicationAddress;
   LPVOID    lpMaximumApplicationAddress;
   DWORD_PTR dwActiveProcessorMask;
   DWORD     dwNumberOfProcessors;
   DWORD     dwProcessorType;
   DWORD     dwAllocationGranularity;
   WORD      wProcessorLevel;
   WORD      wProcessorRevision;
}
 SYSTEM_INFO,  * LPSYSTEM_INFO;


當系統引導時,它要確定這些成員的值是什么。對于任何既定的系統來說,這些值總是相同的,因此決不需要為任何既定的進程多次調用該函數。

表14-1 與內存有關的成員函數

成員名 描述
d w P a g e S i z e 用于顯示C P U的頁面大小。在x86 CPU上,這個值是4 0 9 6字節。在Alpha CPU 上,這個值是8 1 9 2字節。在I A - 6 4上,這個值是8 1 9 2字節
l p M i n i m u m A p p l i c a t i o n A d d r e s s 用于給出每個進程的可用地址空間的最小內存地址。在Windows 98上,這個值是4 194 304,或0 x 0 0 4 0 0 0 0 0,因為每個進程的地址空間中下面的4 M B是不能使用的。在Windows 2000上,這個值是65 536或0 x 0 0 0 1 0 0 0 0,因為每個進程的地址空間中開頭的6 4 K B總是空閑的
l p M a x i m u m A p p l i c a t i o n A d d r e s s 用于給出每個進程的可用地址空間的最大內存地址。在Windows 98 上,這個地址是2 147 483 647或0 x 7 F F F F F F F,因為共享內存映射文件區域和共享操作系統代碼包含在上面的2 GB分區中。在Windows 2000上,這個地址是內核方式內存開始的地址,它不足6 4 K B
d w A l l o c a t i o n G r a n u l a r i t y 顯示保留的地址空間區域的分配粒度。截止到撰寫本書時,在所有Wi n d o w s平臺上,這個值都是65536

該結構的其他成員與內存管理毫無關系,為了完整起見,下面也對它們進行了介紹(見表1 4 - 2)。

 

表14-2 與內存無關的成員函數

成員名 描述
d w O e m I d 已作廢,不引用
W R e d e r v e d 保留供將來使用,不引用
d w N u m b e r O f P r o c e s s o r s 用于指明計算機中的C P U數目
d w A c t i v e P r o c e s s o r M a s k 一個位屏蔽,用于指明哪個C P U是活動的(允許運行線程)
d w P r o c e s s o r Ty p e 只用于Windows 98,不用于Windows 2000,用于指明處理器的類型,如Intel 386、4 8 6或P e n t i u m
w P r o c e s s o r A r c h i t e c t u r e 只用于Windows 2000,不用于Windows 98,用于指明處理的結構,如I n t e l、A l p h a、Intel 64位或Alpha 64位
w P r o c e s s o r L e v e l 只用于Windows 2000,不用于Windows 98,用于進一步細分處理器的結構,如用于設定Intel Pentium Pro或Pentium II
w P r o c e s s o r R e v i s i o n 只用于Windows 2000 ,不用于Windows 98,用于進一步細分處理器的級別

在地址空間中保留一個區域

通過調用Vi r t u a l A l l o c函數,可以在進程的地址空間中保留一個區域:

 

PVOID VirtualAlloc(
PVOID pvAddress,
SIZE_T dwSize,
DWORD fdwAllocationType,
DWORD fdwProtect);

第一個參數p v A d d r e s s包含一個內存地址,用于設定想讓系統將地址空間保留在什么地方。在大多數情況下,你為該參數傳遞M U L L。它告訴Vi r t u a l A l l o c,保存著一個空閑地址區域的記錄的系統應該將區域保留在它認為合適的任何地方。系統可以從進程的地址空間的任何位置來保留一個區域,因為不能保證系統可以從地址空間的底部向上或者從上面向底部來分配各個區域。可以使用M E M _ TO P _ D O W N標志來說明該分配方式。如果Vi r t u a l A l l o c函數能夠滿足你的要求,那么它就返回一個值,指明保留區域的基地址。如果傳遞一個特定的地址作為Vi r t u a l A l l o c的p v A d d r e s s 參數,那么該返回值與傳遞給Vi r t u a l A l l o c的值相同,并被圓整為(如果需要的話) 6 4 K B邊界值。

Vi r t u a l A l l o c函數的第二個參數是d w S i z e,用于設定想保留的區域的大小(以字節為計量單位)。由于系統保留的區域始終必須是C P U頁面大小的倍數,因此,如果試圖保留一個跨越6 2 K B的區域,結果就會在使用4 KB、8 KB或16 KB頁面的計算機上產生一個跨越6 4 K B的區域。

Vi r t u a l A l l o c函數的第三個參數是f d w A l l o c a t i o n Ty p e,它能夠告訴系統你想保留一個區域還是提交物理存儲器(這樣的區分是必要的,因為Vi r t u a l A l l o c函數也可以用來提交物理存儲器)。若要保留一個地址空間區域,必須傳遞M E M _ R E S E RV E標識符作為F d w A l l o c a t i o n Ty p e參數的值。


最后一個參數是f d w P r o t e c t,用于指明應該賦予該地址空間區域的保護屬性。與該區域相關聯的保護屬性對映射到該區域的已提交內存沒有影響。無論賦予區域的保護屬性是什么,如果沒有提交任何物理存儲器,那么訪問該范圍中的內存地址的任何企圖都將導致該線程引發一個訪問違規。

在保留區域中的提交存儲器

當保留一個區域后,必須將物理存儲器提交給該區域,然后才能訪問該區域中包含的內存地址。系統從它的頁文件中將已提交的物理存儲器分配給一個區域。物理存儲器總是按頁面邊界和頁面大小的塊來提交的。

若要提交物理存儲器,必須再次調用Vi r t u a l A l l o c函數。不過這次為f d w A l l o c a t i o n Ty p e參數傳遞的是M E M _ C O M M I T標志,而不是M E M _ R E S E RV E標志。傳遞的頁面保護屬性通常與調用Vi r t u a l A l l o c來保留區域時使用的保護屬性相同(大多數情況下是PA G E _ R E A D W R I T E),不過也可以設定一個不同的保護屬性。

在已保留的區域中,你必須告訴Vi r t u a l A l l o c函數,你想將物理存儲器提交到何處,以及要提交多少物理存儲器。為了做到這一點,可以在p v A d d r e s s參數中設定你需要的內存地址,并在d w S i z e參數中設定物理存儲器的數量(以字節為計量單位)。注意,不必立即將物理存儲器提交給整個區域。
同時進行區域的保留和內存的提交

有時你可能想要在保留區域的同時,將物理存儲器提交給它。只需要一次調用Vi r t u a l A l l o c函數就能進行這樣的操作,如下所示:

 

PVOID pvMem  =  VirtualAlloc(NULL,  99   *   1024 ,   MEM_RESERVE  |  MEM_COMMIT, PAGE_READWRITE);


這個函數調用請求保留一個99 KB的區域,并且將99 KB的物理存儲器提交給它。當系統處理這個函數調用時,它首先要搜索你的進程的地址空間,找出未保留的地址空間中一個地址連續的區域,它必須足夠大,能夠存放100 KB(在4 KB頁面的計算機上)或104 KB(在8 KB頁面的計算機上)。

系統之所以要搜索地址空間,原因是已將p v A d d r e s s參數設定為N U L L。如果為p v A d d r e s s設定了內存地址,系統就要查看在該內存地址上是否存在足夠大的未保留地址空間。如果系統找不到足夠大的未保留地址空間,Vi r t u a l A l l o c將返回N U L L,

如果能夠保留一個合適的區域,系統就將物理存儲器提交給整個區域。無論是該區域還是提交的內存,都將被賦予PA G E _ R E A D W R I T E保護屬性。

最后需要說明的是,Vi r t u a l A l l o c將返回保留區域和提交區域的虛擬地址,然后該虛擬地址被保存在p v M e m變量中。如果系統無法找到足夠大的地址空間,或者不能提交該物理存儲器,Vi r t u a l A l l o c將返回N U L L。
回收虛擬內存和釋放地址空間區域

若要回收映射到一個區域的物理存儲器,或者釋放這個地址空間區域,可調用Vi r t u a l F r e e函數:

 

BOOL VirtualFree(
LPVOID pvAddress,
SIZE_T dwSize,
DWORD fdwFreeType);

改變保護屬性

雖然實踐中很少這樣做,但是可以改變已經提交的物理存儲器的一個或多個頁面的保護屬性。

若要改變內存頁面的保護屬性,可以調用Vi r t u a l P r o t e c t函數:

 

    BOOL VirtualProtect(
   PVOID pvAddress,
   SIZE_T dwSize,
   DWORD flNewProtect,
   PDWORD pflOldProtect);


當然,保護屬性是與內存的整個頁面相關聯的,而不是賦予內存的各個字節的。因此,如果要使用下面的代碼來調用4 KB 頁面的計算機上的Vi r t u a l P r o t e c t函數,其結果是把PA G E _ N O A C C E S S保護屬性賦予內存的兩個頁面:

 

VirtualProtect(pvRgnBase + (3 * 1024), 2 * 1024,
PAGE_NOACCESS, &flOldProtect);

清除物理存儲器的內容


為了說明內存的內容已經被清除,我們必須對系統的R A M提出大量的使用需求。若要進行這項操作,可以分3步來進行:

1) 調用G l o b a l M e m o r y S t a t u s函數,獲取計算機中R A M的總容量。

2) 調用Vi r t u a l A l l o c函數,提交該數量的內存。這項操作的運行速度非常快,因為在進程試圖訪問頁面之前,系統實際上并不為該內存分配R A M。

3) 調用Z e r o M e m o r y函數,使新提交的頁面可以被訪問。這將給系統的R A M帶來沉重的負擔,導致當前正在R A M中的某些頁面被寫入頁文件。

如果用戶指明該數據將在以后被訪問,那么該數據將不被清除,并且在以后訪問該數據時將數據轉入R A M。但是,如果用戶指明以后將不再訪問該數據,那么數據將被清除,并且系統不把數據寫入頁文件,這樣就可以提高應用程序的運行性能。



 

posted on 2006-09-20 18:12 夢在天涯 閱讀(3641) 評論(0)  編輯 收藏 引用 所屬分類: Windows API

公告

EMail:itech001#126.com

導航

統計

  • 隨筆 - 461
  • 文章 - 4
  • 評論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1811982
  • 排名 - 5

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              久久综合给合久久狠狠狠97色69| 亚洲精品日韩一| 午夜视频在线观看一区二区| 国产精品久久国产三级国电话系列 | 香蕉久久夜色精品| 韩国av一区二区三区在线观看| 久久激情五月婷婷| 久久亚洲春色中文字幕久久久| 亚洲欧洲美洲综合色网| 亚洲美女少妇无套啪啪呻吟| 国产精品毛片va一区二区三区 | 国产午夜精品在线| 欧美96在线丨欧| 欧美日韩一区二区免费视频| 亚洲尤物影院| 久久米奇亚洲| 亚洲一区二区欧美| 久久狠狠亚洲综合| 99re这里只有精品6| 一区二区三区黄色| 亚洲大片精品永久免费| 亚洲美女黄色| 精品999成人| 99精品99| 亚洲成人在线观看视频| 99精品国产在热久久婷婷| 国产一区二区三区电影在线观看 | 久久另类ts人妖一区二区| 欧美激情一区三区| 久久久久九九视频| 欧美日本一区二区三区| 久久精品一区| 国产精品盗摄久久久| 女生裸体视频一区二区三区| 国产精品国产精品| 欧美黄色aa电影| 国产一区二区精品久久91| 日韩午夜高潮| 亚洲精品在线免费观看视频| 亚洲欧美中文另类| 亚洲一区二区三区在线观看视频 | 亚洲永久免费| 一区二区高清| 欧美黑人多人双交| 免费日韩视频| 国模私拍一区二区三区| 亚洲视频欧洲视频| 在线亚洲欧美视频| 欧美久久电影| 91久久精品一区| 在线欧美亚洲| 久久久久久欧美| 久久久久一区二区| 国产一区视频在线看| 亚洲欧美日韩高清| 欧美影院精品一区| 国产精品青草综合久久久久99 | 日韩亚洲精品视频| 亚洲精品久久久久| 欧美gay视频| 亚洲国产精品嫩草影院| 亚洲高清在线观看一区| 久久免费黄色| 欧美激情五月| 亚洲精品乱码久久久久久蜜桃91 | 国产区精品在线观看| 亚洲一区欧美激情| 亚洲欧美一区二区三区在线| 国产精品白丝jk黑袜喷水| 99精品免费视频| 亚洲欧美日韩国产一区二区三区 | 香蕉久久久久久久av网站| 久久精品99无色码中文字幕| 韩国一区二区三区在线观看| 久久精品国产欧美激情| 麻豆成人在线| 亚洲精品影院在线观看| 欧美日韩国产色站一区二区三区| 亚洲乱亚洲高清| 午夜视黄欧洲亚洲| 黄色一区二区在线| 欧美岛国激情| 一区二区三区国产精品| 久久成年人视频| 亚洲高清在线| 国产精品白丝av嫩草影院| 欧美在线视频免费播放| 欧美黑人一区二区三区| 亚洲制服av| 亚洲成人资源网| 欧美日韩在线电影| 久久久久国内| 夜夜嗨av色综合久久久综合网| 亚洲欧美国产高清| 亚洲高清视频中文字幕| 欧美三级韩国三级日本三斤| 欧美一区二视频| 亚洲人成网站在线播| 欧美亚洲一区二区三区| 最新中文字幕一区二区三区| 国产精品成人播放| 免费毛片一区二区三区久久久| 99综合在线| 欧美88av| 久久精品一区二区三区不卡| 99re6热在线精品视频播放速度| 国产精品爽爽爽| 欧美精品一区二区三区一线天视频| 亚洲欧美不卡| 日韩午夜av电影| 亚洲福利国产| 久久亚洲午夜电影| 亚洲女性喷水在线观看一区| 最新中文字幕一区二区三区| 国模精品一区二区三区色天香| 欧美性猛交视频| 欧美岛国激情| 老司机免费视频一区二区三区| 亚洲与欧洲av电影| 一区二区三区视频在线| 亚洲国产精品va在看黑人| 久久免费视频观看| 久久精品av麻豆的观看方式| 亚洲欧美成人一区二区三区| 亚洲精品欧美在线| 亚洲国产综合在线看不卡| 黄色精品网站| 国产一区二区av| 国产目拍亚洲精品99久久精品 | 老司机精品导航| 久久精品国产v日韩v亚洲 | 一本色道久久| 日韩午夜中文字幕| 99国产精品自拍| 日韩一区二区福利| 99精品国产一区二区青青牛奶| 99在线精品观看| 日韩一级大片| 99国产精品| 亚洲理论电影网| 一本色道久久综合亚洲二区三区| 亚洲韩国青草视频| 91久久久亚洲精品| 99视频精品| 亚洲一区二区三区乱码aⅴ蜜桃女| 日韩一级大片| 亚洲一区视频在线| 欧美在线高清| 六月婷婷一区| 亚洲国产精品123| 日韩亚洲欧美一区| 在线亚洲国产精品网站| 午夜免费在线观看精品视频| 欧美在线一二三区| 久久人体大胆视频| 男男成人高潮片免费网站| 欧美精品久久99| 国产精品毛片大码女人| 国产综合18久久久久久| 在线看无码的免费网站| 亚洲每日在线| 性久久久久久| 欧美激情精品久久久久久变态| 亚洲精品1区2区| 亚洲一区欧美一区| 蜜桃av一区二区三区| 欧美日韩一区自拍| 国产一区日韩欧美| 日韩视频一区二区三区在线播放| 亚洲一区免费在线观看| 久久久国产一区二区| 亚洲人被黑人高潮完整版| 亚洲一级一区| 欧美激情aⅴ一区二区三区| 国产精品久久久久国产精品日日| 黑人巨大精品欧美黑白配亚洲| 亚洲日本一区二区| 欧美在线视频日韩| 91久久综合| 欧美亚洲专区| 欧美视频一区在线观看| 亚洲大黄网站| 欧美一区二区三区在线观看| 欧美成人一区二区三区在线观看| 中日韩美女免费视频网址在线观看 | 国产精品av久久久久久麻豆网| 在线电影欧美日韩一区二区私密| 亚洲乱码国产乱码精品精可以看 | 午夜日韩电影| 亚洲精品久久久久中文字幕欢迎你 | 欧美人与性动交α欧美精品济南到 | 久久久久久久999| 国产精品久久久久久久久婷婷| 亚洲国产精品va在看黑人| 欧美一区二区成人6969| 亚洲毛片视频| 欧美成人一区二区在线| 狠狠噜噜久久| 久久久久久久综合狠狠综合| 一区二区三区色|