記憶體管理[1]

來源:互聯網
上載者:User
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;    {表示已使用的記憶體比例的一個整數}  dwTotalPhys: DWORD;     {實體記憶體總數}  dwAvailPhys: DWORD;     {可用實體記憶體總數}  dwTotalPageFile: DWORD; {虛擬記憶體總數}  dwAvailPageFile: DWORD; {可用虛擬記憶體總數}  dwTotalVirtual: DWORD;  {虛地址表中的地址總數}  dwAvailVirtual: DWORD;  {虛地址表中可用的地址總數}end;

做個小程式看看記憶體情況:

unit Unit1;interfaceuses  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.

我這裡的運行:


我覺得記憶體這個話題太難了, 如有理解錯誤, 請一定告訴我呀!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.