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

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

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

可以通過調用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函數來檢索內存塊的實際大小:

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 夢在天涯 閱讀(4352) 評論(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

搜索

  •  

積分與排名

  • 積分 - 1815003
  • 排名 - 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久久国产自产拍夜夜嗨| 亚洲福利在线看| 99av国产精品欲麻豆| 在线视频日韩| 久久成人一区二区| 老司机精品导航| 欧美激情综合五月色丁香小说| 欧美成人免费在线观看| 欧美精品在线极品| 国产精品久久一级| 激情久久中文字幕| av成人天堂| 久久xxxx精品视频| 欧美激情小视频| 亚洲一区国产视频| 国产精品99久久久久久久久久久久 | 亚洲一区二区在线免费观看| 午夜欧美不卡精品aaaaa| 久久精品国产成人| 久久久欧美精品| 欧美激情bt| 午夜视频在线观看一区二区三区 | 99国产精品| 久久国产手机看片| 亚洲第一在线视频| 欧美影院视频| 欧美日韩精品二区| 伊人男人综合视频网| 亚洲欧美另类国产| 欧美激情一区二区三区在线| 一本色道久久综合亚洲91| 欧美亚洲一区二区三区| 亚洲高清一区二区三区| 欧美一区激情| 国产精一区二区三区| 一本色道久久综合亚洲精品婷婷| 久久阴道视频| 亚洲欧美日韩成人高清在线一区| 欧美国产91| 亚洲电影专区| 老**午夜毛片一区二区三区| 亚洲午夜一二三区视频| 欧美日韩一区二区三区在线观看免| 欧美在线网址| 国产日韩精品在线观看| 一区二区三区你懂的| 亚洲国产mv| 麻豆精品一区二区av白丝在线| 国产亚洲欧美日韩美女| 欧美一区综合| 欧美一级视频| 国产日韩在线一区| 久久国产精品久久国产精品| 亚洲在线观看视频网站| 国产精品有限公司| 亚洲欧美在线免费观看| 99视频精品| 国产精品白丝av嫩草影院| 亚洲专区一二三| 亚洲精品永久免费| 欧美日韩亚洲一区二区三区在线观看| 日韩视频一区二区三区在线播放免费观看| 欧美h视频在线| 久久精彩视频| 国内自拍一区| 美女诱惑一区| 国产精品久久久久毛片软件 | 国产精品99一区二区| 99热在这里有精品免费| 亚洲高清在线| 欧美三级在线| 欧美一区二区三区四区高清| 亚洲一区二区三区国产| 国产日韩欧美日韩| 久久夜色精品国产| 欧美xxx在线观看| 亚洲小说区图片区| 亚洲欧美日韩一区在线观看| 国产在线拍偷自揄拍精品| 欧美成人一区二区三区在线观看| 欧美刺激性大交免费视频| 亚洲视频二区| 久久久精品一区| 一级成人国产| 久久本道综合色狠狠五月| 亚洲毛片在线看| 亚洲一区二区三区午夜| 黑人巨大精品欧美黑白配亚洲| 亚洲电影网站| 国产美女搞久久| 亚洲国产成人在线播放| 国产欧美精品日韩精品| 欧美韩日视频| 国产欧美三级| 日韩午夜av| 亚洲国产天堂久久国产91| 一本色道久久综合狠狠躁篇的优点| 国产精品揄拍500视频| 亚洲第一黄网| 国产精品影片在线观看| 亚洲国产精品久久| 国产婷婷色一区二区三区四区| 亚洲第一页自拍| 韩国v欧美v日本v亚洲v| 亚洲视频一起| 在线一区二区三区做爰视频网站| 欧美综合77777色婷婷| 亚洲欧美综合国产精品一区| 免费试看一区| 久久伊伊香蕉| 韩国v欧美v日本v亚洲v| 亚洲一区精品在线| 亚洲少妇最新在线视频| 麻豆freexxxx性91精品| 久久久久久999| 国产伦精品一区二区三区高清版 | 亚洲高清不卡在线| 国内偷自视频区视频综合| 一本色道久久综合亚洲二区三区| 亚洲第一页自拍| 久久久久久久成人| 欧美影院在线播放| 久久久亚洲精品一区二区三区 | 欧美日韩中文另类| 嫩草影视亚洲| 国外视频精品毛片| 久久都是精品| 久久午夜国产精品| 国产亚洲第一区| 午夜国产精品影院在线观看| 亚洲男人第一网站| 国产精品九九| 亚洲欧美经典视频| 欧美中文日韩| 国内激情久久| 久久综合色一综合色88| 蜜桃av一区二区在线观看| 精品电影在线观看| 久久蜜桃资源一区二区老牛| 麻豆精品视频在线观看| 在线不卡中文字幕播放| 老司机aⅴ在线精品导航| 亚洲国产高清高潮精品美女| 亚洲精品在线观看免费| 欧美日韩视频免费播放| 亚洲视频一区在线观看| 欧美在线free| 亚洲成色精品| 欧美黑人在线观看| 亚洲视频自拍偷拍| 欧美在线视频导航| 在线看日韩欧美| 欧美日韩国产色站一区二区三区| 亚洲精品综合| 久久精品视频在线看| 亚洲精品黄色| 国产伦精品免费视频| 老司机免费视频久久| 日韩一区二区精品| 久久精品国产91精品亚洲| 亚洲国产高清视频| 欧美日本视频在线| 亚洲无线观看| 欧美va天堂在线| 亚洲综合视频1区| 激情五月***国产精品| 欧美精品在线观看| 久久狠狠久久综合桃花| 日韩亚洲视频在线| 久久久久久亚洲精品杨幂换脸| 亚洲精品日韩在线| 国产精品永久| 欧美精品免费播放| 欧美有码视频| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美激情免费观看| 午夜精品久久久久| 亚洲第一精品夜夜躁人人躁| 欧美日韩精品中文字幕| 久久狠狠一本精品综合网| 欧美大片91| 欧美第十八页| 亚洲欧美精品中文字幕在线| 伊人久久大香线| 欧美午夜视频网站| 久久综合国产精品| 亚洲无线一线二线三线区别av| 欧美jizz19hd性欧美| 欧美专区日韩视频| 99精品视频免费观看视频| 在线成人av| 黄色av日韩| 国产亚洲欧美一区| 国产精品一区视频| 国产精品揄拍500视频| 欧美日韩中文另类|