首頁 > 硬體

記憶體與指標:[1]

2020-10-09 01:55:36

操作方法

  • 01

    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 dobegin    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.
    我這裡的執行效果圖:
    我覺得記憶體這個話題太難了, 如有理解錯誤, 請一定告訴我呀!

  • End

IT145.com E-mail:sddin#qq.com