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

C++ Programmer's Cookbook

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

windows核心編程--內存堆棧

對內存進行操作的第三個機制是使用堆棧。堆棧可以用來分配許多較小的數據塊。例如,若要對鏈接表和鏈接樹進行管理,最好的方法是使用堆棧,堆棧的優點是,可以不考慮分配粒度和頁面邊界之類的問題,集中精力處理手頭的任務。堆棧的缺點是,分配和釋放內存塊的速度比其他機制要慢,并且無法直接控制物理存儲器的提交和回收。
從內部來講,堆棧是保留的地址空間的一個區域。開始時,保留區域中的大多數頁面沒有被提交物理存儲器。當從堆棧中進行越來越多的內存分配時,堆棧管理器將把更多的物理存儲器提交給堆棧。物理存儲器總是從系統的頁文件中分配的,當釋放堆棧中的內存塊時,堆棧管理器將收回這些物理存儲器。

線程的堆棧:

每當創建一個線程時,系統就會為線程的堆棧(每個線程有它自己的堆棧)保留一個堆棧空間區域,并將一些物理存儲器提交給這個已保留的區域。按照默認設置,系統保留1 MB的地址空間并提交兩個頁面的內存。但是,這些默認值是可以修改的,方法是在你鏈接應用程序時設定M i c r o s o f t的鏈接程序的/ S TA C K選項:

/STACK:reserve[,commit]

當創建一個線程的堆棧時,系統將會保留一個鏈接程序的/ S TA C K開關指明的地址空間區域。
進程的默認堆棧

當進程初始化時,系統在進程的地址空間中創建一個堆棧。該堆棧稱為進程的默認堆棧。按照默認設置,該堆棧的地址空間區域的大小是1 MB。但是,系統可以擴大進程的默認堆棧,使它大于其默認值。當創建應用程序時,可以使用/ H E A P鏈接開關,改變堆棧的1 M B默認區域大小。由于D L L沒有與其相關的堆棧,所以當鏈接D L L時,不應該使用/ H E A P鏈接開關。/ H E A P鏈接開關的句法如下:

/HEAP:reserve[,commit]

許多Wi n d o w s函數要求進程使用其默認堆棧。特別是widows提供的API。對默認堆棧的訪問是順序進行的。換句話說,系統必須保證在規定的時間內,每次只有一個線程能夠分配和釋放默認堆棧中的內存塊。如果兩個線程試圖同時分配默認堆棧中的內存塊,那么只有一個線程能夠分配內存塊,另一個線程必須等待第一個線程的內存塊分配之后,才能分配它的內存塊。一旦第一個線程的內存塊分配完,堆棧函數將允許第二個線程分配內存塊。這種順序訪問方法對速度有一定的影響。如果你的應用程序只有一個線程,并且你想要以最快的速度訪問堆棧,那么應該創建你自己的獨立的堆棧,不要使用進程的默認堆棧。

單個進程可以同時擁有若干個堆棧。這些堆??梢栽谶M程的壽命期中創建和撤消。但是,默認堆棧是在進程開始執行之前創建的,并且在進程終止運行時自動被撤消。不能撤消進程的默認堆棧。每個堆棧均用它自己的堆棧句柄來標識,用于分配和釋放堆棧中的內存塊的所有堆棧函數都需要這個堆棧句柄作為其參數。

可以通過調用G e t P r o c e s s H e a p函數獲取你的進程默認堆棧的句柄:

HANDLE GetProcessHeap();

為什么要創建輔助堆棧

除了進程的默認堆棧外,可以在進程的地址空間中創建一些輔助堆棧。由于下列原因,你可能想要在自己的應用程序中創建一些輔助堆棧:

? 保護組件。

? 更加有效地進行內存管理。

? 進行本地訪問。

? 減少線程同步的開銷。

? 迅速釋放。

保護組件
通過創建多個獨立的堆棧,是數據隔離,且相互獨立的操作。
更有效的內存管理

通過在堆棧中分配同樣大小的對象,就可以更加有效地管理堆棧。就是把大小相同的對象放在一個堆棧中進行分配。
進行本地訪問

每當系統必須在R A M與系統的頁文件之間進行R A M頁面的交換時,系統的運行性能就會受到很大的影響。如果經常訪問局限于一個小范圍地址的內存,那么系統就不太可能需要在R A M與磁盤之間進行頁面的交換。

所以,在設計應用程序的時候,如果有些數據將被同時訪問,那么最好把它們分配在互相靠近的位置上。
減少線程同步的開銷

正如下面就要介紹的那樣,按照默認設置,堆棧是順序運行的,這樣,如果多個線程試圖同時訪問堆棧,就不會使數據受到破壞。但是,堆棧函數必須執行額外的代碼,以保證堆棧對線程的安全性。如果要進行大量的堆棧分配操作,那么執行這些額外的代碼會增加很大的負擔,從而降低你的應用程序的運行性能。當你創建一個新堆棧時,可以告訴系統,只有一個線程將訪問該堆棧,因此額外的代碼將不執行。(就是用多個堆棧來減少同步的性能消耗)
迅速釋放堆棧

最后要說明的是,將專用堆棧用于某些數據結構后,就可以釋放整個堆棧,而不必顯式釋放堆棧中的每個內存塊。例如,當Windows Explorer遍歷硬盤驅動器的目錄層次結構時,它必須在內存中建立一個樹狀結構。如果你告訴Windows Explorer刷新它的顯示器,它只需要撤消包含這個樹狀結構的堆棧并且重新運行即可(當然,假定它將專用堆棧用于存放目錄樹信息)。對于許多應用程序來說,這是非常方便的,并且它們也能更快地運行。

如何創建輔助堆棧

你可以在進程中創建輔助堆棧,方法是讓線程調用H e a p C r e a t e函數:

HANDLE HeapCreate(
   DWORD fdwOptions,
   SIZE_T dwInitialSize,
   SIZE_T dwMaximumSize);

當試圖從堆棧分配一個內存塊時, H e a p A l l o c函數(下面將要介紹)必須執行下列操作:

1) 遍歷分配的和釋放的內存塊的鏈接表。

2) 尋找一個空閑內存塊的地址。

3) 通過將空閑內存塊標記為“已分配”分配新內存塊。

4) 將新內存塊添加給內存塊鏈接表。

從堆棧中分配內存塊

若要從堆棧中分配內存塊,只需要調用H e a p A l l o c函數:

PVOID HeapAlloc(
   HANDLE hHeap,
   DWORD fdwFlags,
   SIZE_T dwBytes);

改變內存塊的大小

常常需要改變內存塊的大小。有些應用程序開始時分配的內存塊比較大,然后,當所有數據放入內存塊后,再縮小內存塊的大小。有些應用程序開始時分配的內存塊比較小,后來需要將更多的數據拷貝到內存塊中去時,再設法擴大它的大小。如果要改變內存塊的大小,可以調用H e a p R e A l l o c函數:

PVOID HeapReAlloc(
   HANDLE hHeap,
   DWORD fdwFlags,
   PVOID pvMem,
   SIZE_T dwBytes);

了解內存塊的大小

當內存塊分配后,可以調用H e a p S i z e函數來檢索內存塊的實際大?。?/font>

SIZE_T HeapSize(
   HANDLE hHeap,
   DWORD fdwFlags,
   LPCVOID pvMem);

釋放內存塊

當不再需要內存塊時,可以調用H e a p F r e e函數將它釋放:

BOOL HeapFree(
   HANDLE hHeap,
   DWORD fdwFlags,
   PVOID pvMem);

撤消堆棧

如果應用程序不再需要它創建的堆棧,可以通過調用H e a p D e s t r o y函數將它撤消:

BOOL HeapDestroy(HANDLE hHeap);

調用H e a p D e s t r o y函數可以釋放堆棧中包含的所有內存塊,也可以將堆棧占用的物理存儲器和保留的地址空間區域重新返回給系統。如果該函數運行成功, H e a p D e s t r o y返回T R U E。如果在進程終止運行之前沒有顯式撤消堆棧,那么系統將為你將它撤消。但是,只有當進程終止運行時,堆棧才能被撤消。如果線程創建了一個堆棧,當線程終止運行時,該堆棧將不會被撤消。

在進程完全終止運行之前,系統不允許進程的默認堆棧被撤消。如果將進程的默認堆棧的句柄傳遞給H e a p D e s t r o y函數,系統將忽略對該函數的調用。

由于進程的地址空間中可以存在多個堆棧,因此可以使用G e t P r o c e s s H e a p s函數來獲取現有堆棧的句柄:

DWORD GetProcessHeaps(
   DWORD dwNumHeaps,
   PHANDLE pHeaps);

若要調用G e t P r o c e s s H e a p s函數,必須首先分配一個H A N D L E數組,然后調用下面的函數:

HANDLE hHeaps[25];
DWORD dwHeaps = GetProcessHeaps(25, hHeaps);
if(dwHeaps > 5) 
{
   //More heaps are in this process than we expected.
} 
else
{
   //hHeaps[0] through hHeap[dwHeaps - 1]
   //identify the existing heaps.
}

注意,當該函數返回時,你的進程的默認堆棧的句柄也包含在堆棧句柄的數組中。

H e a p Va l i d a t e函數用于驗證堆棧的完整性:

BOOL HeapValidate(
   HANDLE hHeap,
   DWORD fdwFlags,
   LPCVOID pvMem);

調用該函數時,通常要傳遞一個堆棧句柄,一個值為0的標志(唯一的另一個合法標志是H E A P _ N O _ S E R I A L I Z E),并且為p v M e m傳遞N U L L。然后,該函數將遍歷堆棧中的內存塊以確保所有內存塊都完好無損。為了使該函數運行得更快,可以為參數p v M e m傳遞一個特定的內存塊的地址。這樣做可使該函數只檢查單個內存塊的有效性。

若要合并地址中的空閑內存塊并收回不包含已經分配的地址內存塊的存儲器頁面,可以調用下面的函數:

UINT HeapCompact(
   HANDLE hHeap,
   DWORD fdwFlags);

通常情況下,可以為參數f d w F l a g s傳遞0,但是也可以傳遞H E A P _ N O _ S E R I A L I Z E。

下面兩個函數H e a p L o c k和H e a p U n l o c k是結合在一起使用的:

BOOL HeapLock(HANDLE hHeap);
BOOL HeapUnlock(HANDLE hHeap);

這些函數是用于線程同步的。當調用H e a p L o c k函數時,調用線程將成為特定堆棧的所有者。如果其他任何線程調用堆棧函數(設定相同的堆棧句柄),系統將暫停調用線程的運行,并且在堆棧被H e a p U n l o c k函數解鎖之前不允許它醒來。

H e a p A l l o c、H e a p S i z e和H e a p F r e e等函數在內部調用H e a p L o c k和H e a p U n l o c k函數來確保對堆棧的訪問能夠順序進行。自己調用H e a p L o c k或H e a p U n l o c k這種情況是不常見的。

最后一個堆棧函數是H e a p Wa l k:

BOOL HeapWalk(
   HANDLE hHeap,
   PPROCESS_HEAP_ENTRY pHeapEntry);

該函數只用于調試目的。它使你能夠遍歷堆棧的內容??梢远啻握{用該函數。

zz


posted on 2006-09-21 16:24 夢在天涯 閱讀(4349) 評論(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>
              91久久精品日日躁夜夜躁国产| 欧美激情欧美狂野欧美精品| 国产精品久久久久影院亚瑟| 亚洲精品看片| 99国产精品视频免费观看| 欧美视频中文字幕| 欧美制服丝袜第一页| 久久九九免费视频| 日韩亚洲精品视频| 亚洲天堂免费观看| 一区二区三区在线免费观看| 亚洲福利视频二区| 欧美理论在线| 香蕉亚洲视频| 美女脱光内衣内裤视频久久影院| 亚洲乱码国产乱码精品精98午夜| 一区二区日本视频| 激情久久中文字幕| 亚洲精品少妇30p| 国产午夜精品在线| 欧美激情影院| 国产精品美女一区二区| 欧美成ee人免费视频| 欧美午夜精品久久久久免费视| 久久国内精品自在自线400部| 久久香蕉国产线看观看av| 一区二区三区www| 久久精品91| 中文一区二区| 久久亚洲国产成人| 午夜精品久久久久久久久久久久久| 久久久国产精品一区二区中文| 艳妇臀荡乳欲伦亚洲一区| 欧美综合二区| 亚洲午夜一二三区视频| 老鸭窝91久久精品色噜噜导演| 亚洲免费视频在线观看| 欧美福利电影在线观看| 久久看片网站| 国产精品免费观看视频| 亚洲精品少妇30p| 亚洲国产二区| 欧美在线日韩| 性欧美精品高清| 欧美色网一区二区| 亚洲黄色av| 亚洲日本成人网| 久久琪琪电影院| 国产精品久久久久久av福利软件 | 亚洲欧洲综合另类在线| 香蕉免费一区二区三区在线观看| 久久久久久尹人网香蕉| 欧美一区二区三区四区在线观看| 欧美激情中文字幕在线| 欧美黄色精品| 亚洲成人在线网| 久久久久久伊人| 久热精品视频在线| 国产中文一区二区| 欧美一区二区三区免费观看视频 | 国产精品视频久久久| 亚洲美女啪啪| 一区二区三区国产在线| 欧美劲爆第一页| 91久久精品日日躁夜夜躁国产| 亚洲大片免费看| 欧美成人免费播放| 91久久精品一区二区别| 亚洲美女av黄| 欧美三级日本三级少妇99| 艳女tv在线观看国产一区| 亚洲天堂偷拍| 国产精品第三页| 欧美一区二区黄| 久久综合狠狠综合久久激情| 国产主播在线一区| 免费在线观看一区二区| 亚洲激情婷婷| 亚洲性感美女99在线| 国产精品嫩草久久久久| 欧美一区观看| 欧美福利精品| 亚洲一区二区在线免费观看| 国产精品欧美一区二区三区奶水| 午夜免费日韩视频| 欧美不卡三区| 在线综合视频| 国产一区二区三区视频在线观看| 久久久久久9999| 亚洲国产aⅴ天堂久久| 亚洲免费视频在线观看| 国产在线播放一区二区三区| 久久综合给合久久狠狠狠97色69| 亚洲精品男同| 久久免费偷拍视频| 99精品欧美一区二区三区综合在线| 国产精品久久久久久久免费软件| 久久成人精品| 99国产精品国产精品久久| 久久久久久久尹人综合网亚洲| 亚洲免费大片| 国产亚洲网站| 欧美日韩美女在线观看| 久久精品视频在线播放| 亚洲伦理在线观看| 另类成人小视频在线| 亚洲一区二区在线观看视频| 尤物在线精品| 国产精品亚洲一区| 欧美精品在线观看播放| 久久精品视频播放| 亚洲视频视频在线| 亚洲人成亚洲人成在线观看| 国产精品video| 欧美mv日韩mv亚洲| 久久综合网络一区二区| 午夜久久影院| 一区二区三区欧美在线观看| 在线国产亚洲欧美| 国产欧美日韩在线观看| 欧美伦理91i| 欧美xart系列高清| 久久久www| 欧美伊人久久久久久午夜久久久久| aa级大片欧美| 亚洲精品欧洲| 亚洲国产一区二区三区青草影视| 久久久免费av| 久久精品视频免费播放| 亚洲综合视频在线| 一区二区三区欧美视频| 99re6热在线精品视频播放速度 | 欧美日韩一区二区高清| 欧美国产第一页| 蜜桃av噜噜一区| 久久综合色婷婷| 久久琪琪电影院| 久久久亚洲午夜电影| 欧美在线1区| 欧美中文在线观看国产| 欧美一区二区三区精品 | 亚洲狼人精品一区二区三区| 亚洲夫妻自拍| 亚洲精品视频在线| 亚洲人屁股眼子交8| 亚洲人成毛片在线播放| 日韩午夜精品| 亚洲深夜福利网站| 亚洲欧美日韩在线播放| 欧美一二三视频| 久久成人综合网| 麻豆精品精品国产自在97香蕉| 久久综合给合| 欧美日韩国产123区| 欧美视频在线观看| 国产精品自在线| 国产中文一区二区| 亚洲国产成人精品女人久久久| 亚洲国产精品久久久久婷婷884| 亚洲欧洲精品一区二区三区波多野1战4 | 一区二区三区四区精品| 亚洲视频一区在线| 亚洲欧美国产毛片在线| 久久国产精品久久久久久电车 | 亚洲高清久久网| 亚洲另类一区二区| aⅴ色国产欧美| 性色av一区二区三区| 久久精品国产清高在天天线| 欧美大尺度在线| 国产精品毛片大码女人| 韩国久久久久| 夜夜嗨av一区二区三区中文字幕| 午夜精品亚洲| 欧美高清不卡| 亚洲砖区区免费| 免费av成人在线| 国产精品女同互慰在线看| 激情成人在线视频| 免费在线亚洲| 国产精品爽爽爽| 亚洲韩国日本中文字幕| 亚洲一区二区三区四区在线观看| 久久久久99| 亚洲深夜福利| 欧美不卡视频| 国产专区欧美精品| 亚洲午夜激情在线| 欧美福利一区二区| 欧美一级视频一区二区| 欧美日韩福利| 亚洲国产一区二区a毛片| 国产亚洲一区二区精品| 亚洲调教视频在线观看| 欧美a级片网站| 香蕉久久夜色精品| 国产精品mv在线观看| 亚洲三级免费电影| 免费在线观看成人av| 午夜精品视频一区|