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

內存管理[1]

編輯:Delphi

Windows 是多任務的操作系統, 一個任務就是一個應用(應用程序)、一個應用占一個進程; 在一個進程裡面, 又可以運行多個線程(所以就有了很多"多線程編程"的話題).

  對 Win32 來講, 系統給每個進程 4GB 的地址空間:

  低端 2GB($00000000 - $7FFFFFFF) 給用戶支配;

  高端 2GB($80000000 - $FFFFFFFF) 留給系統使用.

  文件或程序要調入內存才能工作, 先看看我們的內存到底有多大吧.

  在系統盤根目錄下有個 pagefile.sys 文件, 這就是我們的 "虛擬內存"(虛擬內存是以文件的形式存在的).

  把 pagefile.sys 叫做 "虛擬內存" 似乎不妥, 所謂的 "虛擬" 只是相對真實的物理內存(RAM)來講的; 很多書上的 "物理內存" 指的其實是: RAM + 虛擬內存, 也就是所有可用內存.

  "虛擬內存" 在有些書上也被稱作 "頁文件" 、"頁面文件" 或 "交換文件". "虛擬內存" 的大小可以從 "控制面板" 裡設置, 默認是由系統自動管理的.

  使用 "虛擬內存" 是系統的機制, 不管 RAM 有多大, 也應該使用 "虛擬內存".

  RAM 大了, 系統就會少用 "虛擬內存", 從而提高速度; 但 RAM 也不是越大越好, 如果你真的放 4G 的內存條, 系統能夠識別並使用的也就是 3G 左右, 因為 Win32 只有 4G 的管理能力(尋址能力), 當然這在 Win64 下要另當別論.

  所謂系統給每個程序 4G, 是給 4G 的 "虛擬的地址表", 絕不是真實的內存, 不然一個記事本、一個計算器就得需要 8G.

  這個 "虛擬的地址表" 在有些書上叫 "虛地址表"、"頁映射表" 或 "虛內存地址", 也有叫 "虛擬內存地址", 很容易和 "虛擬內存" 的概念混淆.

 這個 "虛擬的地址表" 上有 4G 個(4294967296 個)地址(0 - $FFFFFFFF), 雖然每個程序都有這樣一個表, 但它們並不會沖突, 就因為這些地址是虛擬的, 系統在需要的時候會把它們映射成具體的真實內存的地址. 這樣就阻斷了一個進程對另一個進程的訪問.

  在 Win2000 以前的版本中, 用 GlobalAlloc 申請公用內存, 用 LocalAlloc 申請私有內存; 現在通過 "虛擬的地址表" 使用內存, 在進程中申請的內存都是私有的, 現在的 GlobalAlloc、LocalAlloc 沒有區別, 都是執行同樣的代碼.

  如果需要跨進程的公用內存空間, 需要用 "內存映射" 等手段, 這需要再專題學習.

  總結概念: 物理內存、虛擬內存、虛地址表.

  函數 GlobalMemoryStatus 可以獲取它們的信息, 獲取後放在 TMemoryStatus 結構中.//TMemoryStatus 是 _MEMORYSTATUS 的重命名:
_MEMORYSTATUS = record
 dwLength: DWord;    {結構長度}
 dwMemoryLoad: DWord;  {表示可用內存比例的一個整數, 100 表示內存都可用}
 dwTotalPhys: DWord;   {物理內存總數}
 dwAvailPhys: DWord;   {可用物理內存總數}
 dwTotalPageFile: DWord; {虛擬內存總數}
 dwAvailPageFile: DWord; {可用虛擬內存總數}
 dwTotalVirtual: DWord; {虛地址表中的地址總數}
 dwAvailVirtual: DWord; {虛地址表中可用的地址總數}
end;
做個小程序看看內存情況:unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 TForm1 = class(TForm)
  Memo1: TMemo;
  procedure FormCreate(Sender: TObject);
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
 m: TMemoryStatus;
const
 num = 1024 * 1024;
begin
 GlobalMemoryStatus(m);
 Memo1.Clear;
 with Memo1.Lines do begin
  Add(Format('dwLength:'    + #9 + '%d', [m.dwLength]));
  Add(Format('dwMemoryLoad:'  + #9 + '%d', [m.dwMemoryLoad]));
  Add(Format('dwTotalPhys:'   + #9 + '%d', [m.dwTotalPhys div num]));
  Add(Format('dwAvailPhys:'   + #9 + '%d', [m.dwAvailPhys div num]));
  Add(Format('dwTotalPageFile:' + #9 + '%d', [m.dwTotalPageFile div num]));
  Add(Format('dwAvailPageFile:' + #9 + '%d', [m.dwAvailPageFile div num]));
  Add(Format('dwTotalVirtual:' + #9 + '%d', [m.dwTotalVirtual div num]));
  Add(Format('dwAvailVirtual:' + #9 + '%d', [m.dwAvailVirtual div num]));
 end;
end;
end.
我這裡的運行效果圖:

內存管理[1]

 

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