Delphi7 之 記憶體篇 三

2022-07-29 08:48:07 字數 3008 閱讀 2841

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