Windows任務管理器原理+內存管理機密+揭穿內存優化工具的騙局
我們在瀏覽網頁時,也許會經常看到一些彈出廣告,例如“整理內存碎片、提升系統性能”、或者“大大減少系統和程序崩潰的可能性,回收垃圾內存”等等。如果點擊這些彈出廣告鏈接,則會看到某些所謂的優化軟件,聲稱只需花費9.95、14.95或者29.95美元,就可以輕松實現所有的功能。看上去,這些工具軟件確實不錯,但是實際上最好的情況,這些所謂的內存優化工具沒有任何效用;而最差的情況,則可能會嚴重降低系統性能。
盆盆評注 在國內,廣告語更加精彩,“讓您的系統運行如飛”、“讓Windows插翅能飛”,充分體現漢語的優越性。
市面上這些所謂的“內存優化工具”有很多—有些是商業軟件,有些則是自由軟件。可能我們已經在系統上安裝了這些軟件。這些軟件到底能夠起什么作用?它們是怎樣試圖愚弄我們,讓我們誤認為它們可以達到所承諾的目的? 那就讓我們一起好好分析一下內存優化程序的內部原理,看看它們如何讓Windows內存計數器顯示出誘人的結果。
用戶界面
通常,內存優化工具會在用戶界面上顯示一個圖形標簽,以表明當前的可用內存,還會顯示一個指示條,以表明當前設置的閾值,超過這個閾值,該工具就會開始行動(所謂的優化內存)。還有一個指示條,用來顯示優化工具可以釋放的內存容量。通常用戶可以配置以上兩種或者其中一種設置,還可以手動觸發內存優化,或者設置計劃任務。某些工具還會詳細顯示執行過程。
當執行內存優化的計劃任務時,通常這些程序的可用內存計數器會上升,有時候還可以顯示動態效果,給人的感覺好像是這些工具確實正在釋放內存,以供我們的應用程序使用。要理解這些內存優化工具如何讓可用內存的數字不斷上升,我們必須理解Windows是如何管理物理內存的。
Windows內存管理
和大多數現代操作系統一樣,Windows實現按需調頁的虛擬內存機制。由于操作系統使用了虛擬內存,這就給應用程序造成了一個假象,以為計算機安裝的內存遠遠超過自己所需要的數量。
在32位的Windows計算機上,進程具有4GB的虛擬內存地址空間,操作系統通常會把這4GB的地址空間劃分為進程和系統兩個部分。因此,每個進程可以獲得2GB的虛擬內存,根據可用的容量。分配給所有進程的虛擬內存總數不能超過頁面文件和大多數物理內存的總和(操作系統本身也要占據一小部分物理內存)。
有了這種機制,加上足夠大的頁面文件,就可以給進程分配超過物理內存容量的虛擬內存,Windows內存管理子系統必須讓多個進程和緩存的文件數據(由緩存管理器管理)共享物理內存。如圖1所示,內存管理器給每個進程(例如Windows Explorer、記事本和Word)指派一部分物理內存,這叫做進程的工作集。可分頁的內核和驅動程序部分,加上可分頁的內核內存緩沖區(叫做分頁池),還有緩存管理器所管理的物理內存,它們具有自己的工作集,叫做系統工作集。

圖1
盆盆譯注:可分頁表示可以經過調頁轉移到頁面文件上,以便空出可用內存供其他進程使用。但是有些重要部分是不可以進行分頁的,例如內存管理器本身就不能分頁,還有憑據緩存里的重要憑據信息(例如長期密鑰、Kerberos票據等)都不能進行分頁。
工作集就是進程在物理內存中的部分,可以用一個隊列(數據結構)來表示。也就是說如果進程訪問的頁在工作集里,就不會發生頁面錯誤事件。話反過來說,如果進程所需訪問的頁不在工作集中,就必須進行分頁操作。
內存管理器可以擴展或者縮短系統和進程的工作集,以便讓進程可以快速訪問其代碼和數據。計算機的內存管理硬件設備要求Windows按照“頁”的塊級別來管理工作集和虛擬內存。在32位的x86處理器上,頁通常是4096字節(4KB)。然而操作系統和其他需要大量訪問內存的應用程序,也可以使用4MB的“頁”,以便優化性能。
盆盆譯注:為什么使用4MB的“頁”可以優化性能?通過閱讀《Windows Internals》第七章內存管理部分,我們可以了解到,Windows的內存管理采用TLB的硬件數據結構來緩存頁表里的數據。如果采用4MB的頁,由于總的頁數比較少,TLB緩存中的項就不需要經常刷新,這樣就不會由于TLB里沒有緩存,而被迫到頁表里讀取地址,以增加性能。
但是為什么不默認采用4MB,而要采用4KB呢? 《Windows Internals》進一步提到,由于頁需要采用保護機制,大的頁面不利于設置更細微的保護粒度。例如在4MB的數據中,一部分需要只讀訪問,另一部分需要讀寫訪問,則整個頁只能設置為讀寫訪問。
如果進程所訪問的虛擬內存頁不在工作集中,進程就會觸發一個頁面錯誤的硬件異常。如果發生這種情況,內存管理器會分配一個可用的物理內存頁,以存放最近訪問的數據。另外,內存管理器可能會給進程工作集添加新的頁,以擴展進程的工作集。然而,如果內存管理器認為進程的工作集已經足夠大了,它就會把工作集中的一個頁調出去,以便騰出空間存放新的頁。替換的策略是選擇進程最近最少訪問的頁,這主要是假設進程在未來訪問該頁的可能性很小。
當內存管理器把頁從進程的工作集中移走,它必須決定應該怎樣處理這個頁。如果該頁已經修改過了,內存管理器會首先把它放到已修改列表中,這個列表中的頁最終會寫入到頁面文件,或者寫入這些頁所對應的內存映射文件中。內存管理器會把頁從已修改列表移動到備用列表中。未修改的頁會直接移動到備用列表中。所以,我們可以把備用列表看成是文件數據的緩存。
盆盆譯注:總結一下,當進程的工作集已滿,想要訪問新的頁,則必須把老的頁移走。這些老的頁,如果已經修改過,則會移動到已修改列表,如果沒有修改過,則會移動到備用列表。
到現在為止,物理內存的兩個列表(數據結構)已經出來了,一個是備用列表,另一個是已修改列表。
可用內存
在本文的前面部分,曾經提到發生頁面錯誤時,內存管理器會給進程提供一個可用的物理內存頁,但是還沒有討論什么叫做可用內存。物理內存中的備用列表就是內存管理器所認為的一部分可用內存。其他一部分可用內存,它們的頁所包含的數據屬于已釋放的虛擬內存(例如這些頁包含已退出進程的數據);還有一部分可用內存,包含剛被釋放的頁,這些頁隨后會被內存管理器的低優先級頁清零線程用全零來填充。這些類型的頁分別保存在內存管理器的自由列表和清零頁列表中。
盆盆譯注:物理內存的另外兩個列表(數據結構)自由列表和清零頁列表。可用內存由三部分(三個數據結構)組成:備用列表、自由列表和清零頁列表,正如圖1所示的那樣。
圖2顯示了工作集和這些頁列表之間的轉化。系統線程每秒鐘喚醒一次,調用內存管理器的工作集管理程序,對系統和進程工作集進行分析。如果發現可用內存很低,工作集管理程序就會挑選一些進程,這些進程在過去的一秒鐘里頁面錯誤發生率最低,然后從它們的工作集中移走一些頁。這些移走的頁會轉移到已修改列表或者備用列表(還記得盆盆前面的注釋吧),這樣就可以騰出可用內存了(盆盆譯注:其實只有備用列表里的部分,才算是可用內存)。這種協調機制的其中一個重要的副作用是:如果系統需要為其他進程分配內存,內存管理器會從空閑進程的工作集中抽取內存頁。所以,空閑進程的工作集會最終消失,這意味著,如果進程長時間處于空閑狀態,那么最終它們將不會占據任何物理內存。

圖2 盆盆漢化 版權所有
如果進程需要請求新的物理內存頁,內存管理器首先會查看該頁是不是位于備用列表或者已修改頁列表。如果該頁曾經從進程工作集中移走,并且沒有因為其他目的而被其他進程重新使用,那么該頁應該還在這兩個列表里(盆盆譯注:就是指備用列表或者已修改列表)。把內存頁重新拿回,并放到進程的工作集中,這叫做軟頁面錯誤,因為和這硬頁面錯誤不一樣,軟頁面錯誤不需要從硬盤的頁面文件或者其他文件中讀入數據。
如果所需請求的內存頁并不在備用列表或者已修改列表中,內存管理器就會從某個列表上摘取一頁,首先會檢查自由列表,然后是清零頁列表,最后是備用列表(盆盆譯注:這也再次說明了,可用內存由這三部分組成)。如果可用內存不夠,內存管理器會觸發平衡集管理器,來調整進程的工作集,以便生成上述的三個列表,從而獲得可用內存。如果內存管理器不得不從自由列表、備用列表或者清零頁列表中移除內存頁,以便重新使用,它會確定如何訪問目標代碼或者數據,這會導致從頁面文件或者進程映像文件中讀取數據,或者創建由零填充的數據—如果應用程序需要分配新的數據,而且所獲得的內存頁并不是取自清零頁列表(盆盆譯注:如果是從清零頁列表中獲取的頁,則無需再由零填充,因為本來就已經清零了)。
創建可用內存
理解了內存管理器的行為,現在我們可以把目光轉向內存優化工具的行為。內存優化工具所顯示的可用內存數值,等同于任務管理器的“性能”標簽頁上所顯示的“可用數”,如圖3所示。可用內存的數值是備用列表、自由列表和清零頁列表這三個數值的相加。而系統緩存,則是備用列表和系統工作集這兩個數值的相加。在Windows NT 4.0和以前的版本,文件緩存則只等于系統工作集的大小。

圖3 盆盆制作 版權所有
盆盆譯注:這部分的內容很好地解釋了任務管理器“性能”標簽頁里的術語,什么叫做可用內存,什么叫做系統緩存。
內存管理器可以分配、然后釋放一大塊虛擬內存,內存優化工具正是利用了內存管理器的這一特點。內存優化工具的作用如圖4所示。最上方的條狀圖顯示優化之前的工作集和可用內存。中間的條狀圖顯示內存優化工具(RAM optimizer)發出大內存的請求,在極短的時間里產生大量的頁面錯誤。作為回應,內存管理器會增加內存優化工具的工作集。這種工作集的擴展是以犧牲可用內存作為代價—這時候可用內存會變得很低—同時以減少其他進程的工作集作為代價。最下方的條狀圖顯示,內存優化工具會釋放內存,內存管理器會把所有的內存頁從它的工作集中轉移到自由列表中,所以可用內存會大大增加。絕大多數的內存優化工具隱藏了第一階段中可用內存急劇下降的事實,但是如果我們在優化的時候啟動任務管理器,就可以看到可用內存在最初會急劇下降。

圖4
盡管從表面上來看,可用內存越多越好,其實不然。內存優化工具雖然使得可用內存數大大增加,但是它們會強迫其他進程的數據和代碼交換出內存。假設我們正在運行Word,當內存優化工具強制增加可用內存時,Word的打開文檔和程序代碼原本是在內存中(工作集),結果不得不從磁盤中重新讀入,我們才能繼續編輯文檔。在服務器上,這種性能的損失將會變得非常嚴重,這是因為緩存在備用列表和系統工作集中的文件數據(還有活動服務端進程所擁有的代碼和數據)很可能會丟失。
盆盆譯注:所謂的內存優化工具,是以犧牲其他進程的性能作為代價,同時還會導致系統重要進程的代碼和數據交換到磁盤,對于總體性能來說,得不償失。Windows Vista的內存管理,并沒有強調可用內存足夠多,而是確保內存里包含正確的內容,這樣才能盡可能地減少磁盤I/O,提升整體的用戶體驗。
其他的宣傳功效
一些廠商宣傳他們的內存優化產品還具有其他一些功能。例如該優化工具可以把一些無用進程所占據的內存釋放出來,例如運行在任務欄通知區域上的進程。這些所謂的功效都是不正確的,因為Windows已經自動調整了空閑進程的工作集。內存管理器已經具有所有必需的內存優化功能。
盆盆譯注:盆盆在Windows Vista做實驗,證實了Mark Russinovich的說法。以Daemon Tool為例,平時空閑的時候,其工作集只有3MB左右(專用工作集只有350KB),而當打開其配置界面時(使其不處于空閑狀態時),其工作集達到10MB左右(專用工作集也達到約3MB)。如圖5所示,綠色部分代表空閑時的工作集,而紫色部分代表活動時(Active)的工作集大小。另外要注意,Windows Vista中文版的翻譯有誤,Working Set,不能翻譯為工作設置,而應該是工作集。

圖5 盆盆制作 版權所有
內存優化工具的開發者拋出的另外一個謬論,就是他們的產品可以對內存碎片進行整理。 分配一大塊虛擬內存,然后再釋放,也許會生成一大片物理連續的可用內存。然而,由于虛擬內存對進程屏蔽了物理內存的布局,進程不能直接從虛擬內存(由連續的物理內存所提供)中得益。當進程運行時,由于工作集的調整和擴展,雖然有一大片連續的可用內存,但是進程的虛擬內存到物理內存的映射,還是會產生很多碎片。
獲得連續的可用內存,對以下情況是有利的:
當內存管理器希望能夠最大化CPU高速緩存的效率時,會采用一種叫做“頁面染色”(Page Coloring)的機制,以確定從自由列表(或清零頁列表)中把哪些內存頁分配給進程。
盡管如此,雖然獲得連續的可用內存,可以獲得一點好處,但是這種好處要以把有用的代碼和數據移出內存作為代價,是得不償失的。
盆盆譯注:為了進一步了解什么叫做“頁面染色”機制,盆盆費心在網上搜索不少資料,終于了解到以下的背景資料(經過縮寫):
為了確保在進程上下文切換時,CPU高速緩存里的內容不受影響,現代CPU的L1 Cache會對物理內存頁進行緩存,而不是緩存虛擬內存頁(否則的話,上下文切換時,必須刷新緩存中的內容,導致緩存性能急劇下降)。這就要求相鄰的虛擬內存頁最好分配相鄰的物理內存頁,以獲得最好的L1 Cache性能。
更具體的內容,可以參考這篇文檔。
最后,軟件開發商宣傳他們的內存優化工具可以重新獲取因泄漏而丟失的內存。這種宣傳可能是最虛假的說法。
在所有時刻,內存管理器都知道進程所擁有的物理內存和虛擬內存。然而,如果進程分配內存,但是由于Bug而無法釋放內存(內存泄漏),內存管理器就可能無法了解這些已分配的內存無法重新訪問,而必須等到進程退出時回收內存。
哪怕產生內存泄漏的進程無法退出,內存管理器的工作集調整機制也會最終從進程的工作集中“盜取”所有的物理頁(分配給泄漏的虛擬內存)。該進程會把泄漏的虛擬頁發送到頁面文件,這樣系統就可以騰出物理內存挪作它用。所以對可用物理內存來說,內存泄漏只有有限的影響。真正的影響在于虛擬內存的消耗(在任務管理器中叫做PF使用率和提交更改,如圖3所示)。沒有任何工具可以解決這種虛擬內存的消耗,除非殺死消耗內存的進程。
欺詐軟件
筆者(Mark Russinovich)還在尋找能夠實踐其承諾的內存優化工具。如果仔細查看,我們會經常發現開發商會在其網站上隱藏著冗長的免責聲明,其中包括本文所述的內容—該產品可能對系統性能沒有什么影響,甚至可能導致性能下降。甚至無需知道這些產品是如何借助內存管理器來實現其具有明顯視覺效果、具有煽情名字的內存管理機制,只要用正常思維就可以明白如果這種內存優化機制是可行的話(而且那么多三流廠商都可以實現),微軟的開發工程師早就應該在內核里實現這種功能。
盆盆譯注:說實話,國外的廠商還算是講點道義,畢竟還提供一些免責聲明。看看國內的情況,騙子太多了,例如讓人哭笑不得的“智慧星”,還有無孔不入的抄襲者,不提也罷~~
原文信息