内存管理一
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 = recorddwLength: DWORD; {結構長度}dwMemoryLoad: DWORD; {表示已使用的內存比例的一個整數}dwTotalPhys: DWORD; {物理內存總數}dwAvailPhys: DWORD; {可用物理內存總數}dwTotalPageFile: DWORD; {虛擬內存總數}dwAvailPageFile: DWORD; {可用虛擬內存總數}dwTotalVirtual: DWORD; {虛地址表中的地址總數}dwAvailVirtual: DWORD; {虛地址表中可用的地址總數} end;
做個小程序看看內存情況:
unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; typeTForm1 = class(TForm)Memo1: TMemo;procedure FormCreate(Sender: TObject);end; varForm1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); varm: TMemoryStatus; constnum = 1024 * 1024; beginGlobalMemoryStatus(m);Memo1.Clear;with Memo1.Lines do beginAdd(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.
總結
- 上一篇: CSS3:linear-gradient
- 下一篇: 服务器群集解决方案