2013.07.26 09:05

想讓電腦更快更順嗎?系統最佳化,深入Windows記憶體管理

ADVERTISEMENT

分頁檔是經常被討論的效能調校選項,該怎麼調?說法卻五花八門。有的人說留個幾百MB就好、有的則是堅持要放到RAM Disk裡加速,反正微軟從來都不願意提供標準答案。你可能甚至嚐試關閉它過,但你真的瞭解變更後對系統的影響嗎?

快速瀏覽:

  • 記憶體管理機制/減少硬碟存取來提高效能

在進一步討論分頁檔前,我們必需先了解一下記憶體的管理機制。基本上,Windows的記憶體管理最高指導原則是「隨時隨地讓實體記憶體裡的可用空間最大化,優先給重要的資料及程式使用,並且還要在此條件下盡量避免硬碟的寫入或讀取動作」,要做到這一點,得透過不少複雜的機制配合才行。

分頁檔有2種

系統根目錄下常見的2個分頁檔分別是pagefile.sys與swapfile.sys,更早期的作業系統可能還會有不同的名字,如win386.swp。

pagefile.sys是Windows NT核心作業系統採用的分頁檔。swapfile.sys則是Windows 8新加入的成員,專門用來應付Metro Apps的分頁需求,用來與傳統應用程式的pagefile.sys做區別。

記憶體管理機制

記憶體最小的管理單位,是「分頁」(Page),如果我們把整塊記憶體比喻成公寓,那麼分頁就是居住單位。每個單位可以住的人數多寡不一,分頁的大小則是從4KB~16MB不等,視系統架構而定,愈大的存取效率就愈高、但是也會產生一些不良的副作用。大容量分頁多在特殊伺服器上才會出現,一般個人電腦的架構設計都是4KB。

ADVERTISEMENT

開機時,作業系統會將資料從硬碟裡載入到實體記憶體的分頁裡。有部分的分頁得存放重要的系統資料,比如底層的系統服務或驅動程式,所以會被分類成「Non-Paged Pool」,除非終止系統服務或驅動程式,不然Non-Paged Pool裡的分頁是不能被移動的,同時也代表它們不能進入分頁檔。

其它的分頁存在於「Paged Pool」,用來裝載一般應用程式及其產生的資料。Paged Pool裡的分頁會不斷的在記憶體裡漂流著,並在有必要時存入分頁檔裡。

分頁的奇幻漂流

首先,作業系統開完機時,大部分的可用記憶體,也就是空白分頁都會存在「Zeroed Page List」清單裡。當某個程序執行時,會向作業系統要求記憶體來載入及存放資料。

ADVERTISEMENT

比如開啟記事本時得把notepad.exe裡頭的程式碼載入記憶體才能執行,作業系統便會優先從Zeroed Page List裡挪出部分分頁放到該程序持有的「Working Set」(工作集)裡,讓程序能把資料放進去。

工作集就是該程序所持有的分頁總和,一般情況下只有該程序能存取它(除了一些共享的部分),它會因為程序的要求而可能逐漸成長。當這個總和太大、或是Windows基於最高指導原則決定限制它的時候,就會逼它釋出一定的分頁量來節省或釋放出更多的記憶體,因為這些被踢出的分頁通常很已經很久沒有被存取了,不如把空間挪給正需要、或是即將需要分頁的程序,以維持最大效益。

設定緩衝提高效率

被推出的分頁們就消失了嗎?當然不是。Windows設了好幾層緩衝機制來提高記憶體的回收使用效率。

ADVERTISEMENT

除非十分急迫,不然被踢出的分頁並不會馬上被抹除來給其它程序使用,同時這些分頁裡其實還保有舊程序需要的資料,舊程序還在執行中,它們不能消失,所以Windows會暫時將它們放在2個清單裡,分別是「Standby List」與「Modified List」。

清單依重要性分類

Standby List裡存放的分頁通常是無關緊要的、可以隨時抹除的內容,比如上述notepad.exe的程式碼、或是讀入記憶體後還沒修改過的資料,因為這些資料隨時都可以再從硬碟裡的notepad.exe或其它相關檔案裡讀取。

至於Modified List裡頭則是程式產生的、原本不在檔案裡的資料,或是從檔案載入記憶體後被修改過的分頁,像是打開記事本後才輸入的文字、或是RPG遊戲裡NPC的觸發記錄等等,它們在還沒存檔前不能被抹除,所以會先待在Modified List裡。

ADVERTISEMENT

講得更明白一點,位於這2個清單內的分頁隨時都可以再丟回原程序的工作集裡使用,但是它們的所有權已經不屬於原程序了。不屬於原程序的分頁在被原程序要求存取時會產生「Page Fault」(分頁錯誤),我們待會再仔細說明。

未雨綢繆勝於臨渴掘井

隨著愈來愈多程式被啟動,Zeroed List裡的分頁會愈來愈少。Windows並不會等到Zeroed List裡的分頁都被用完了才想辦法,它會優先從Standby List裡取出優先權較低、也就是不太可能會再被原程序讀取的分頁,把它丟到「Free Page List」裡。同時如果有某個程序被關閉了,所屬工作集及Standby List、Modified List裡的分頁也會跑到Free Page List,Free Page List裡的分頁通常會馬上被清空,並釋放到Zeroed Page List裡,如此便完成了分頁的資源回收。

大部分的分頁回收,都只是實體記憶體裡分頁抹除再利用,對系統效能幾無影響。Modified List則是比較特別的地方,因為已變更的分頁在抹除前得先存回硬碟。

當Windows決定從裡頭取用分頁時,會啟動「Modified Page Writer」這個程序來把分頁裡的資料寫入硬碟,然後再將其歸類成Standby List,讓分頁繼續它們的生命旅程。這個「寫入硬碟」的動作,一部分的分頁會寫入程序自己的檔案,而另一部分就是寫入我們熟悉的分頁檔pagefile.sys。

從分頁們的移動策略及路線,我們不難歸納出Windows分配記憶體的首要原則就是「能省則省」。儘管主機裡裝了再多的記憶體,Windows都會認為應該把它們花在每個程序的刀口上,跟一般玩家持有的「既然實體記憶體還有空間就要先用完」的觀念大相逕庭。

下圖為PFN資料庫裡的分頁清單分類圖。每個區塊都紀錄著分頁的不同狀態,箭頭則是這些分頁的傳遞流程。在實體記憶體上,分頁並沒有真的被移動,移動的是資料以及分頁的歸屬狀態。同時程序本身也不需要知道自己的工作集裡有哪些分頁、或者是哪些分頁已經被移出了,它只知道系統配給它多少虛擬位址空間,就能跟系統要多少記憶體。只要實體或分頁檔的空間足夠,工作集的上限可以成長到用完虛擬位址空間為止。

▲點圖看大圖

減少硬碟存取來提高效能

Windows會在記憶體壓力不大時就先把閒置分頁寫入分頁檔,避免等到程序要求空白記憶體時才進行這個動作,就好像不應該有客人在玄關了才在打掃客廳一樣,造成不必要的等待。然而有利必有弊,過度依賴分頁檔仍然會讓系統效能大打折扣,這就得從Windows的分頁查詢方式談起。

分頁檔不能直接當RAM用

分頁檔雖然可稱作虛擬記憶體,但它只是用來存放實體記憶體放不下的閒置分頁,並不能夠直接被程序取用。很多人會以為分頁檔就是延伸在硬碟上的可用記憶體,這是不甚正確的想法。

前面提過,每個程序都會有自己的工作集,工作集裡頭的分頁只能存在實體記憶體裡,所以分頁檔裡的資料還是得先讀回實體記憶體才能被程序存取。反過來看,當工作集要取用空白分頁時,也一定是對應到實體記憶體裡的空白位置,而不是到分頁檔裡找空間,因為分頁檔裡的空間是用來放被踢出工作集的資料。

打個比方。假設某間健身房只有10台跑步機、卻同時有20人要使用,這時候就只能先請使用時間已滿、或是佔著器材光看電視的奧客先到休息室等待,以挪出空間給新來的使用者。你不可能請馬上要健身的人到休息室發呆,而在休息室待夠的人如果要健身也一定要再回到健身房。套用此例,健身房的角色好比實體記憶體,而分頁檔就是分頁們的休息室。

實體與虛擬位址

實體記憶體有自己的實體位址(Physical Address),然而只有實體位址是不夠的,早在大型主機萌芽的時期,程式執行時所需的資料量就已經遠大於昂貴的記憶體元件,程式設計師們不可能針對每種帶有不同容量記憶體的主機各寫份程式碼,加上有遠見的科學家們預知了未來的資料處理方式將採多工走向,於是虛擬位址(Virtual Address)就這麼被設想及實作出來。

虛擬位址的存在目的是為了畫出一大塊連續而整齊的定址空間,應用程式們只需要透過虛擬位址來存取分頁、而不必知道分頁存放在實體記憶體或分頁檔裡的真正位置,在記憶體管理課題裡是非常重要的一個核心概念。如此一來,應用程式只要送出虛擬位址的查詢需求,作業系統便能將其轉譯並映射到實體記憶體或硬碟上的分頁。

分頁只是虛擬位址畫分出來的、定位到實體記憶體及分頁檔裡的固定空間。套用到前文內容,其實分頁們根本就沒有「漂流」,改變的是實體記憶體裡的內容以及它們的歸屬狀態、還有虛擬位址對應到的實體位址或在分頁檔裡的位置。

位址轉換

下圖是經過極度簡化的位址空間對應圖。每個程序在執行時都會有自己的虛擬位址空間,經過好幾層轉譯後對應到實體記憶體的分頁上。這麼一來,程序本身就不必去煩惱該把資料放在實體記憶體上的什麼位置,何況有可能跟本沒位置放。加上實體記憶體裡的分頁通常是零散而不集中的,連續而大塊的虛擬位址空間在取用及管理上也會比較方便。

延伸閱讀:

(後面還有更多內容!)

ADVERTISEMENT

這裡可以買:http://www.chinesean.com/affiliate/clickBanner.do?wId=54967&pId=11857&cId=20045