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

C++ Programmer's Cookbook

{C++ 基礎(chǔ)} {C++ 高級} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

windows核心編程--內(nèi)存堆棧

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

線程的堆棧:

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

/STACK:reserve[,commit]

當(dāng)創(chuàng)建一個(gè)線程的堆棧時(shí),系統(tǒng)將會保留一個(gè)鏈接程序的/ S TA C K開關(guān)指明的地址空間區(qū)域。
進(jìn)程的默認(rèn)堆棧

當(dāng)進(jìn)程初始化時(shí),系統(tǒng)在進(jìn)程的地址空間中創(chuàng)建一個(gè)堆棧。該堆棧稱為進(jìn)程的默認(rèn)堆棧。按照默認(rèn)設(shè)置,該堆棧的地址空間區(qū)域的大小是1 MB。但是,系統(tǒng)可以擴(kuò)大進(jìn)程的默認(rèn)堆棧,使它大于其默認(rèn)值。當(dāng)創(chuàng)建應(yīng)用程序時(shí),可以使用/ H E A P鏈接開關(guān),改變堆棧的1 M B默認(rèn)區(qū)域大小。由于D L L沒有與其相關(guān)的堆棧,所以當(dāng)鏈接D L L時(shí),不應(yīng)該使用/ H E A P鏈接開關(guān)。/ H E A P鏈接開關(guān)的句法如下:

/HEAP:reserve[,commit]

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

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

可以通過調(diào)用G e t P r o c e s s H e a p函數(shù)獲取你的進(jìn)程默認(rèn)堆棧的句柄:

HANDLE GetProcessHeap();

為什么要?jiǎng)?chuàng)建輔助堆棧

除了進(jìn)程的默認(rèn)堆棧外,可以在進(jìn)程的地址空間中創(chuàng)建一些輔助堆棧。由于下列原因,你可能想要在自己的應(yīng)用程序中創(chuàng)建一些輔助堆棧:

? 保護(hù)組件。

? 更加有效地進(jìn)行內(nèi)存管理。

? 進(jìn)行本地訪問。

? 減少線程同步的開銷。

? 迅速釋放。

保護(hù)組件
通過創(chuàng)建多個(gè)獨(dú)立的堆棧,是數(shù)據(jù)隔離,且相互獨(dú)立的操作。
更有效的內(nèi)存管理

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

每當(dāng)系統(tǒng)必須在R A M與系統(tǒng)的頁文件之間進(jìn)行R A M頁面的交換時(shí),系統(tǒng)的運(yùn)行性能就會受到很大的影響。如果經(jīng)常訪問局限于一個(gè)小范圍地址的內(nèi)存,那么系統(tǒng)就不太可能需要在R A M與磁盤之間進(jìn)行頁面的交換。

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

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

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

如何創(chuàng)建輔助堆棧

你可以在進(jìn)程中創(chuàng)建輔助堆棧,方法是讓線程調(diào)用H e a p C r e a t e函數(shù):

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

當(dāng)試圖從堆棧分配一個(gè)內(nèi)存塊時(shí), H e a p A l l o c函數(shù)(下面將要介紹)必須執(zhí)行下列操作:

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

2) 尋找一個(gè)空閑內(nèi)存塊的地址。

3) 通過將空閑內(nèi)存塊標(biāo)記為“已分配”分配新內(nèi)存塊。

4) 將新內(nèi)存塊添加給內(nèi)存塊鏈接表。

從堆棧中分配內(nèi)存塊

若要從堆棧中分配內(nèi)存塊,只需要調(diào)用H e a p A l l o c函數(shù):

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

改變內(nèi)存塊的大小

常常需要改變內(nèi)存塊的大小。有些應(yīng)用程序開始時(shí)分配的內(nèi)存塊比較大,然后,當(dāng)所有數(shù)據(jù)放入內(nèi)存塊后,再縮小內(nèi)存塊的大小。有些應(yīng)用程序開始時(shí)分配的內(nèi)存塊比較小,后來需要將更多的數(shù)據(jù)拷貝到內(nèi)存塊中去時(shí),再設(shè)法擴(kuò)大它的大小。如果要改變內(nèi)存塊的大小,可以調(diào)用H e a p R e A l l o c函數(shù):

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

了解內(nèi)存塊的大小

當(dāng)內(nèi)存塊分配后,可以調(diào)用H e a p S i z e函數(shù)來檢索內(nèi)存塊的實(shí)際大?。?/font>

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

釋放內(nèi)存塊

當(dāng)不再需要內(nèi)存塊時(shí),可以調(diào)用H e a p F r e e函數(shù)將它釋放:

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

撤消堆棧

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

BOOL HeapDestroy(HANDLE hHeap);

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

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

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

DWORD GetProcessHeaps(
   DWORD dwNumHeaps,
   PHANDLE pHeaps);

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

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.
}

注意,當(dāng)該函數(shù)返回時(shí),你的進(jìn)程的默認(rèn)堆棧的句柄也包含在堆棧句柄的數(shù)組中。

H e a p Va l i d a t e函數(shù)用于驗(yàn)證堆棧的完整性:

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

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

若要合并地址中的空閑內(nèi)存塊并收回不包含已經(jīng)分配的地址內(nèi)存塊的存儲器頁面,可以調(diào)用下面的函數(shù):

UINT HeapCompact(
   HANDLE hHeap,
   DWORD fdwFlags);

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

下面兩個(gè)函數(shù)H e a p L o c k和H e a p U n l o c k是結(jié)合在一起使用的:

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

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

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等函數(shù)在內(nèi)部調(diào)用H e a p L o c k和H e a p U n l o c k函數(shù)來確保對堆棧的訪問能夠順序進(jìn)行。自己調(diào)用H e a p L o c k或H e a p U n l o c k這種情況是不常見的。

最后一個(gè)堆棧函數(shù)是H e a p Wa l k:

BOOL HeapWalk(
   HANDLE hHeap,
   PPROCESS_HEAP_ENTRY pHeapEntry);

該函數(shù)只用于調(diào)試目的。它使你能夠遍歷堆棧的內(nèi)容??梢远啻握{(diào)用該函數(shù)。

zz


posted on 2006-09-21 16:24 夢在天涯 閱讀(4353) 評論(0)  編輯 收藏 引用 所屬分類: Windows API

公告

EMail:itech001#126.com

導(dǎo)航

統(tǒng)計(jì)

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

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1816188
  • 排名 - 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>
              国产精品v欧美精品v日本精品动漫| 亚洲人成在线观看一区二区| 亚洲一二三区精品| 午夜一级久久| 国产一区二区三区高清播放| 久久成人免费网| 欧美激情视频一区二区三区在线播放| **欧美日韩vr在线| 欧美电影免费观看高清完整版| 91久久精品一区| 国产欧美日韩亚洲一区二区三区| 亚洲一二区在线| 久色成人在线| 亚洲国产另类久久久精品极度| 欧美大片在线观看一区| 亚洲精选久久| 久久福利影视| 亚洲国产成人久久综合| 欧美揉bbbbb揉bbbbb| 小黄鸭视频精品导航| 奶水喷射视频一区| 亚洲夜晚福利在线观看| 国产亚洲激情在线| 欧美经典一区二区三区| 亚洲欧美日产图| 亚洲国产一区二区三区a毛片 | 一区二区欧美视频| 国产精品久久久久久五月尺| 久久久久91| 一本久道综合久久精品| 蜜桃av久久久亚洲精品| 一区二区三区不卡视频在线观看 | 国产精品日韩久久久| 久久人人爽爽爽人久久久| 亚洲免费观看高清在线观看| 久久久www成人免费精品| 日韩一级黄色av| 很黄很黄激情成人| 欧美视频精品在线| 久热成人在线视频| 亚洲在线视频| 亚洲激情不卡| 久久久久九九九九| 亚洲手机视频| 亚洲国产精品久久久久| 国产精品高潮久久| 蘑菇福利视频一区播放| 亚洲欧美日韩综合国产aⅴ| 欧美激情精品久久久| 欧美中文在线观看| 亚洲私人影院| 日韩一级精品| 亚洲激情六月丁香| 狠狠色噜噜狠狠狠狠色吗综合| 欧美四级伦理在线| 亚洲午夜视频在线| 免费中文日韩| 久久久久久婷| 欧美一级大片在线免费观看| 日韩视频免费大全中文字幕| 欧美激情精品久久久| 久久中文字幕一区| 蜜臀av在线播放一区二区三区| 亚洲一区二区高清视频| av成人免费在线| 亚洲精品一级| 最新国产拍偷乱拍精品 | 美女精品国产| 久久婷婷av| 久久视频一区二区| 久久理论片午夜琪琪电影网| 久久精品国产久精国产一老狼| 性欧美在线看片a免费观看| 久久精品国产成人| 欧美一区二区三区免费看| 午夜精品视频在线观看| 亚洲自拍16p| 亚洲欧美一区二区精品久久久| 亚洲一区免费看| 亚洲欧美日韩综合| 亚洲欧美日韩精品在线| 亚洲欧美日韩国产综合在线| 午夜在线精品| 久久久久9999亚洲精品| 亚洲精品免费电影| 99国产麻豆精品| 亚洲肉体裸体xxxx137| 日韩视频不卡| 亚洲午夜未删减在线观看| 亚洲免费人成在线视频观看| 欧美一区二区三区四区视频| 久久久久久夜精品精品免费| 久久亚洲不卡| 欧美人与性动交α欧美精品济南到| 欧美日韩成人综合| 国产精品久久9| 国产一区二区三区高清播放| 亚洲国产精品久久久久婷婷老年 | 亚洲精品综合在线| 这里只有精品丝袜| 欧美一二三区在线观看| 久久久久国产精品人| 欧美福利视频网站| 亚洲理论电影网| 亚洲欧美日韩在线播放| 久久欧美肥婆一二区| 欧美精品久久99久久在免费线| 欧美亚州一区二区三区| 国内精品写真在线观看| 亚洲精品永久免费| 欧美一区二区福利在线| 欧美成黄导航| 在线一区观看| 久久精品国产久精国产思思| 欧美噜噜久久久xxx| 亚洲国产合集| 午夜天堂精品久久久久 | 久久精品水蜜桃av综合天堂| 免费久久精品视频| 国产精品久久久久9999高清| 国产欧美日韩激情| 亚洲人成人77777线观看| 亚洲欧美精品一区| 欧美岛国激情| 亚洲欧美国产高清va在线播| 欧美a一区二区| 国产日本欧美一区二区| 亚洲精品视频在线观看网站| 性欧美办公室18xxxxhd| 亚洲黄色天堂| 亚洲欧美综合网| 欧美激情中文字幕乱码免费| 国产视频一区免费看| 日韩亚洲精品电影| 久久久国产精品亚洲一区 | 99香蕉国产精品偷在线观看| 欧美在线精品免播放器视频| 亚洲电影免费观看高清完整版| 亚洲一区二区三区在线视频| 欧美激情视频网站| 在线成人激情| 欧美一级久久| 一本色道久久综合亚洲精品按摩 | 欧美日本一区二区高清播放视频| 国内精品久久久久久久果冻传媒| 亚洲影视在线| 日韩亚洲精品电影| 欧美精品一区二区三区很污很色的| 黄色欧美成人| 久久香蕉国产线看观看av| 午夜国产不卡在线观看视频| 国产精品久久久久久亚洲调教 | 久久国产一区二区| 国产亚洲一区二区三区| 翔田千里一区二区| 一本久道久久综合中文字幕| 免费在线亚洲欧美| 亚洲电影免费在线观看| 99视频精品| 亚洲国产99精品国自产| 久久精品国产99| 国产日产欧美精品| 国产精品99久久99久久久二8| 欧美高清在线视频| 欧美专区中文字幕| 国产精品亚洲综合久久| 亚洲视频日本| 亚洲先锋成人| 欧美亚男人的天堂| 中文国产成人精品久久一| 久久久999精品免费| 久久精品国产久精国产一老狼| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 欧美日韩三级电影在线| 在线观看av一区| 久久国产直播| 亚洲欧美日韩系列| 国产主播精品| 久久精品视频va| 欧美一区免费视频| 国产欧美日韩激情| 欧美一区日韩一区| 亚洲欧美激情四射在线日 | 亚洲尤物视频在线| 99国内精品久久| 国产精品入口日韩视频大尺度| 亚洲视频网在线直播| 一本久久a久久精品亚洲| 欧美另类一区二区三区| 亚洲综合国产激情另类一区| 99视频在线精品国自产拍免费观看 | 久久久www成人免费精品| 黑人极品videos精品欧美裸| 久久国产精品一区二区三区| 久久精品国产精品亚洲精品| 激情五月综合色婷婷一区二区| 麻豆国产精品777777在线| 性一交一乱一区二区洋洋av| 精品999久久久| 欧美二区不卡|