virtualalloc 分配的記憶體是以 4k 為最小單位、連續的記憶體位址(但對映到真實的記憶體時它不一定是連續的), 前面說了, 它不適合分配小記憶體(譬如只有幾個位元組的變數); 區域性的變數在 "棧" 中有程式自動管理, 那麼那些全域性的小變數怎麼辦呢? 這就要用到 "堆".
這樣看來, virtualalloc 分配的記憶體既不是 "棧" 也不是 "堆"; virtualalloc 分配的記憶體位址是連續的, "堆" 中內容一般是不連續的, 所以管理 "堆" 比較麻煩, 它是通過雙線鍊錶的結構方式管理的; 程式可以擁有若干個 "堆", 每乙個 "堆" 都會有乙個控制代碼, 訪問 "堆" 中的內容時先要找到這個 "堆", 然後再遍歷鍊錶, 這可能就是 "堆" 比 "棧" 慢的根本原因.
在 "堆" 中分配記憶體(heapalloc)前先要建立 "堆"(heapcreate), 就像程式有預設的 "棧" 一樣, 每乙個程式都有乙個預設建立的 "堆"(可以用 getprocessheap 獲取這個 "預設堆" 的控制代碼), 我們在 delphi 中用到 "堆" 時, 使用的就是這個 "預設堆". 如果讓程式更靈活地擁有多個 "堆", 必須要用到 api 函式.建立 "堆" 時會同時提交真實記憶體的, 這在申請大記憶體時會很慢, 所以預設堆也只有 1m, 但 "預設堆" 並沒有限制大小, 它會根據需要動態增長.
有了 "預設堆" 還有必要申請其他的 "堆" 嗎? 這只有在多執行緒中才能體現出來, 和 "棧" 不一樣, 程式會給每個執行緒分配乙個 "棧區"; 而 "預設堆" 是程序中的所有執行緒公用的, 當乙個執行緒使用 "預設堆" 時, 另乙個需要使用 "堆" 的執行緒就要先掛起等待, 也就是它們不能同時使用; 只有通過 api 函式重新建立的私有堆才是互不干涉、最有效率的.
先了解一下 "堆" 相關的函式.
//建立堆; 注意建立時指定的尺寸也是按頁大小(pagesize)對齊的, 譬如指定 15k, 實際會分配 16k.heapcreate(
floptions: dword;
dwinitialsize: dword;
dwmaximumsize: dword
): thandle;
//floptions 引數可選值:
heap_no_serialize = 1;
heap_generate_exceptions = 4;
heap_zero_memory = 8;
//floptions 引數指定有 heap_generate_exceptions 時, 可能返回的異常:
status_access_violation = dword($c0000005);
status_no_memory = dword($c0000017);
//銷毀堆
heapdestroy(
hheap: thandle
): bool; {}
//從堆中申請記憶體
heapalloc(
hheap: thandle;
dwflags: dword;
dwbytes: dword
): pointer;
//dwflags 引數可選值:
heap_no_serialize = 1;
heap_generate_exceptions = 4;
heap_zero_memory = 8;
//改變堆記憶體的大小, 也就是重新分配
heaprealloc(
hheap: thandle;
dwflags: dword;
lpmem: pointer;
dwbytes: dword
): pointer;
//dwflags 引數可選值:
heap_no_serialize = 1;
heap_generate_exceptions = 4;
heap_zero_memory = 8;
heap_realloc_in_place_only = 16;
//獲取堆中某塊記憶體的大小heapsize(
hheap: thandle;
dwflags: dword;
lpmem: pointer
): dword;
//釋放堆中指定的記憶體塊heapfree(
hheap: thandle;
dwflags: dword;
lpmem: pointer
): bool; {}
//驗證堆heapvalidate(
hheap: thandle; {}
dwflags: dword; {}
lpmem: pointer {}
): bool; {}
//整理堆heapcompact(
hheap: thandle; {}
dwflags: dword {}
): uint; {}
//鎖定堆heaplock(
hheap: thandle {}
): bool; {}
//鎖定後的解鎖heapunlock(
hheap: thandle {}
): bool; {}
//列舉堆中的記憶體塊heapwalk(
hheap: thandle; {}
var lpentry: tprocessheapentry
{}): bool; {}
Delphi7遠端除錯
自己的開發機器稱為主機,執行程式的機器稱為目標機 一 在主機編譯執行程式 1 project options linker中的exe and dll options選項組中的include remote debug symbols打上勾,這樣就可以生成rsm為副檔名的檔案,該檔名稱於你的專案同名。2...
Delphi7 動態陣列
初學delphi,感覺.這感覺就是寫 太費勁了,已經習慣了c 那種信手拈來,不能說pascal不適應只能說還是費勁,可能是d7太老了,也可能是我還沒有上道兒,就這麼著吧,下面簡單的寫倆函式作為參考,修改修改可以當c 中的list 用arr array of string procedure add ...
Delphi7 元件篇 之 TBevel元件
tbevel元件 該元件可以建立具有3d效果的斜角的盒子 方框或線。常用屬性 shape 設定邊界形狀 style 設定分解的框線在螢幕上是凸起還是凹下。shape屬性 type tbevelshape bsbox,bsframe,bstopline,bsbottomline,bsleftline,...