程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 內存管理[2]

內存管理[2]

編輯:Delphi

 系統給程序的地址數是 4G, 為什麼不是 3G 或 5G? 因為 32 位的指針的最大值就是 $FFFFFFFF, 它不能表示更多了, 究其根源這要回到 CPU 的尋址能力、地址總線等等.

  在 Win64 下, 系統給程序的地址數達到了 16EB(0 - $FFFFFFFFFFFFFFFF), 也就是 18446744073709551616 個. 不過 Win64 還沒有普及, 我們還得回到實際的 Win32.

  就這 4G 的地址, 系統還要留下一半($80000000 - $FFFFFFFF, 這 2G 是各進程共享的)用作宏觀管理; 只給程序 2G(0 - $7FFFFFFF).

  就這 2G 的地址, 也不是全給用戶的, 低端的 0 - $FFFF 是用於空指針分配, 禁止訪問; 高端的 $7FFF0000 - $7FFFFFFF 也留出來作為進程的臨界區, 也禁止訪問. 其實進程的私有空間地址只有 $10000 - $FFEFFFF.

  上面這個結果, 我們可以通過 GetSystemInfo 函數得到證實, 通過 GetSystemInfo 函數能獲取一個 TSystemInfo 結構, 結構中的 lpMinimumApplicationAddress 和 lpMaximumApplicationAddress 分別表示程序(或動態鏈接庫)可以訪問的最低與最高的內存地址.var
 si: TSystemInfo;
begin
 GetSystemInfo(si);
 ShowMessageFmt('%p-%p', [si.lpMinimumApplicationAddress, si.lpMaximumApplicationAddress]);
 {結果是: 00010000-7FFEFFFF}
end;
通過 GetSystemInfo 還能得到一個內存相關的重要參數: 頁大小(PageSize)var
 si: TSystemInfo;
begin
 GetSystemInfo(si);
 ShowMessage(IntToStr(si.dwPageSize)); {4096; 4096 字節也就是 4K}
end;
PageSize 是系統管理內存的基本單位, 之所以需要用 GetSystemInfo 獲取不同系統的 PageSize 也會有區別.

  我們需要知道的是, 用 VirtualAlloc 函數分配的內存就是以 PageSize(4K) 為最小單位的; 假如我們用 VirtualAlloc 給一個整數(4個字節)分配內存, 將會浪費 4092 個字節, 也就是說 VirtualAlloc 不適合分配小內存, 因而也有了多種分配內存的函數.

  暫時放下這個話題, 先了解一下 "棧".

  說到 "棧", 就想到 "堆", 還有 "堆棧" 指的也是 "棧"; "棧" 與 "堆" 都是程序可操作的內存區域($10000 - $FFEFFFF)中的某一小段.

  系統函數中有 HeapReAlloc、GlobalAlloc 等分配 "堆" 的函數, 卻沒有分配 "棧" 的函數, 這是因為 "棧" 是程序自動管理的; 每個程序都從自己的可用地址范圍內留出一塊作為 "棧", 程序根據需要可以自動調節它的大小, 但咱們可以設置它的最大值與最小值. 在Delphi 中可以從這裡設置:

  Project -> Options -> Linker -> [Min stack size 和 Max stack size]

  "棧" 用來暫存局部變量和函數參數, 由程序在需要時申請, 用完就釋放.

  因為 "棧" 的空間一般不是很大, 所以咱們一般不要把局部變量弄得太大(特別是在使用數組的時候);

  因為訪問 "棧" 比訪問 "堆" 來的簡潔, 速度快, 所以要盡量多用局部變量、少用全局變量.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved