小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

內(nèi)存管理[3]

 獨(dú)孤求財(cái) 2012-03-30
VirtualAlloc 分配的內(nèi)存是以 4K 為最小單位、連續(xù)的內(nèi)存地址(但映射到真實(shí)的內(nèi)存時(shí)它不一定是連續(xù)的), 前面說(shuō)了, 它不適合分配小內(nèi)存(譬如只有幾個(gè)字節(jié)的變量); 局部的變量在 "棧" 中有程序自動(dòng)管理, 那么那些全局的小變量怎么辦呢? 這就要用到 "堆".

這樣看來(lái), VirtualAlloc 分配的內(nèi)存既不是 "棧" 也不是 "堆"; VirtualAlloc 分配的內(nèi)存地址是連續(xù)的, "堆" 中內(nèi)容一般是不連續(xù)的, 所以管理 "堆" 比較麻煩, 它是通過(guò)雙線鏈表的結(jié)構(gòu)方式管理的; 程序可以擁有若干個(gè) "堆", 每一個(gè) "堆" 都會(huì)有一個(gè)句柄, 訪問(wèn) "堆" 中的內(nèi)容時(shí)先要找到這個(gè) "堆", 然后再遍歷鏈表, 這可能就是 "堆" 比 "棧" 慢的根本原因.

在 "堆" 中分配內(nèi)存(HeapAlloc)前先要建立 "堆"(HeapCreate), 就像程序有默認(rèn)的 "棧" 一樣, 每一個(gè)程序都有一個(gè)默認(rèn)建立的 "堆"(可以用 GetProcessHeap 獲取這個(gè) "默認(rèn)堆" 的句柄), 我們?cè)?Delphi 中用到 "堆" 時(shí), 使用的就是這個(gè) "默認(rèn)堆". 如果讓程序更靈活地?fù)碛卸鄠€(gè) "堆", 必須要用到 API 函數(shù).

建立 "堆" 時(shí)會(huì)同時(shí)提交真實(shí)內(nèi)存的, 這在申請(qǐng)大內(nèi)存時(shí)會(huì)很慢, 所以默認(rèn)堆也只有 1M, 但 "默認(rèn)堆" 并沒(méi)有限制大小, 它會(huì)根據(jù)需要?jiǎng)討B(tài)增長(zhǎng).

有了 "默認(rèn)堆" 還有必要申請(qǐng)其他的 "堆" 嗎? 這只有在多線程中才能體現(xiàn)出來(lái), 和 "棧" 不一樣, 程序會(huì)給每個(gè)線程分配一個(gè) "棧區(qū)"; 而 "默認(rèn)堆" 是進(jìn)程中的所有線程公用的, 當(dāng)一個(gè)線程使用 "默認(rèn)堆" 時(shí), 另一個(gè)需要使用 "堆" 的線程就要先掛起等待, 也就是它們不能同時(shí)使用; 只有通過(guò) API 函數(shù)重新建立的私有堆才是互不干涉、最有效率的.

先了解一下 "堆" 相關(guān)的函數(shù).
//建立堆; 注意建立時(shí)指定的尺寸也是按頁(yè)大小(PageSize)對(duì)齊的, 譬如指定 15k, 實(shí)際會(huì)分配 16K.
HeapCreate(
  flOptions: DWORD;     {堆屬性選項(xiàng), 見(jiàn)下表}
  dwInitialSize: DWORD; {初始尺寸, 單位是字節(jié); 該大小會(huì)被直接提交到實(shí)際的內(nèi)存}
  dwMaximumSize: DWORD  {最大尺寸, 如果不限定最大值就設(shè)為 0}
): THandle;             {返回堆句柄; 失敗返回 0, 但如果參數(shù) flOptions 允許了異常, 失敗會(huì)返回異常標(biāo)識(shí)}

//flOptions 參數(shù)可選值:
HEAP_NO_SERIALIZE        = 1; {非互斥, 此標(biāo)記可允許多個(gè)線程同時(shí)訪問(wèn)此堆}
HEAP_GENERATE_EXCEPTIONS = 4; {當(dāng)建立堆出錯(cuò)時(shí), 此標(biāo)記可激發(fā)一個(gè)異常并返回異常標(biāo)識(shí)}
HEAP_ZERO_MEMORY         = 8; {把分配的內(nèi)存初始化為 0}

//flOptions 參數(shù)指定有 HEAP_GENERATE_EXCEPTIONS 時(shí), 可能返回的異常:
STATUS_ACCESS_VIOLATION = DWORD($C0000005); {參數(shù)錯(cuò)誤}
STATUS_NO_MEMORY        = DWORD($C0000017); {內(nèi)存不足}

//銷毀堆 HeapDestroy( hHeap: THandle {堆句柄} ): BOOL;      {}
//從堆中申請(qǐng)內(nèi)存 HeapAlloc(   hHeap: THandle; {堆句柄}   dwFlags: DWORD; {內(nèi)存屬性選項(xiàng), 見(jiàn)下表}   dwBytes: DWORD  {申請(qǐng)內(nèi)存的大小, 單位是字節(jié)} ): Pointer;      {返回內(nèi)存指針; 失敗返回 0 或異常, 情況和建立堆是一樣} //dwFlags 參數(shù)可選值: HEAP_NO_SERIALIZE        = 1; {非互斥, 此標(biāo)記可允許多個(gè)線程同時(shí)訪問(wèn)此堆} HEAP_GENERATE_EXCEPTIONS = 4; {當(dāng)建立堆出錯(cuò)時(shí), 此標(biāo)記可激發(fā)一個(gè)異常并返回異常標(biāo)識(shí)} HEAP_ZERO_MEMORY        = 8; {把分配的內(nèi)存初始化為 0} {能看出這和堆的屬性選項(xiàng)是一樣的; 如果 dwFlags 參數(shù)設(shè)為 0, 將使用堆的屬性; 如果重新指定將覆蓋堆的屬性} {另外: 如果堆是默認(rèn)堆, 也就是堆句柄來(lái)自 GetProcessHeap, dwFlags 參數(shù)會(huì)被忽略}
//改變堆內(nèi)存的大小, 也就是重新分配 HeapReAlloc(   hHeap: THandle; {句柄}   dwFlags: DWORD; {內(nèi)存屬性選項(xiàng); 該參數(shù)比 HeapAlloc 多出一個(gè)選項(xiàng), 見(jiàn)下表}   lpMem: Pointer; {原內(nèi)存指針}   dwBytes: DWORD  {新的尺寸} ): Pointer;      {同 HeapAlloc} //dwFlags 參數(shù)可選值: HEAP_NO_SERIALIZE          = 1{非互斥, 此標(biāo)記可允許多個(gè)線程同時(shí)訪問(wèn)此堆} HEAP_GENERATE_EXCEPTIONS  = 4{當(dāng)建立堆出錯(cuò)時(shí), 此標(biāo)記可激發(fā)一個(gè)異常并返回異常標(biāo)識(shí)} HEAP_ZERO_MEMORY          = 8{把分配的內(nèi)存初始化為 0} HEAP_REALLOC_IN_PLACE_ONLY = 16; {此標(biāo)記不允許改變?cè)瓉?lái)的內(nèi)存位置}
//獲取堆中某塊內(nèi)存的大小 HeapSize(   hHeap: THandle; {堆句柄}   dwFlags: DWORD; {內(nèi)存屬性; 可選值是 0 或 HEAP_NO_SERIALIZE, 后者可確保同步訪問(wèn)}   lpMem: Pointer  {內(nèi)存指針} ): DWORD;        {成功返回字節(jié)為單位的大小; 失敗返回 $FFFFFFFF}
//釋放堆中指定的內(nèi)存塊 HeapFree(   hHeap: THandle; {堆句柄}   dwFlags: DWORD; {內(nèi)存屬性; 可選值是 0 或 HEAP_NO_SERIALIZE}   lpMem: Pointer  {內(nèi)存指針} ): BOOL;          {}
//驗(yàn)證堆 HeapValidate(   hHeap: THandle; {}   dwFlags: DWORD; {}   lpMem: Pointer  {} ): BOOL;          {}
//整理堆 HeapCompact(   hHeap: THandle; {}   dwFlags: DWORD  {} ): UINT;          {}
//鎖定堆 HeapLock(   hHeap: THandle {} ): BOOL;        {}
//鎖定后的解鎖 HeapUnlock(   hHeap: THandle {} ): BOOL;        {}
//列舉堆中的內(nèi)存塊 HeapWalk(   hHeap: THandle;                {}   var lpEntry: TProcessHeapEntry {} ): BOOL;                        {}
舉例放下篇吧.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多