Windows 內存釋放軟體的原理是什麼?

諸如騰訊電腦管家之類的軟體


我寫過一個。就是申請一塊超大內存,循環讀寫幾百次,然後釋放。這樣整塊內存都會被調入物理內存,保證物理內存夠空。

然而完全沒意義。


簡單回答:沒用。

技術回答:內存頁面分配的相關技術。

科普回答:

內存以頁為單位進行管理。內存頁可以保存在內存中,也可以保存在本地的頁面文件中。

所謂的內存清理,就是一個程序不停申請內存,從而不停的觸發操作系統的內存重分配策略。直到用完系統可用的內存後再宣布釋放內存,就把這些內存變成了空的狀態。

在這個情況下,內存頁的影響分以下幾種:

1 當前程序正在使用的內存頁:不動。

2 當前程序暫時並沒有使用的內存頁:寫入硬碟的頁面文件,並釋放。如果當前程序要使用,就只能從頁面文件再讀回來。

3 IO的讀緩存:刪除。

4 IO的寫緩存:寫入完成後刪除。

在Windows正常管理的情況下,對於前面的幾種情況:

1 當前程序正在使用的內存頁:不動。

2 當前程序暫時並沒有使用的內存頁:當有程序需要內存的時候,且3、4無法滿足時,寫入頁面文件並標記為可以使用。但如果一直沒有被使用。而當前程序又需要的時候,就可以直接再分配給這個程序。由於數據沒有被清除,就不必再讀一次硬碟。

3 IO的讀緩存:不常用後,刪除。

4 IO的寫緩存:寫入完成後刪除。

所以結果是,只有兩種情況下有效:

1 好看。

2 做好準備,為了用最快的速度迎接下一次大內存分配。比如你打算玩一個大型遊戲,而想儘可能的加快載入時間,可以先做一次內存整理的動作。但實際上考慮到內存整理本身的時間,其實總時間就需要更多。

但是,就算你不人工觸發內存整理的動作,當程序需要內存而當前沒有可用內存的時候,操作系統自己就會按需觸發內存重新分配的上述動作。

而由於放棄了讀緩存,並強制寫入暫時沒有使用的內存頁到硬碟,還在之後可能需要再從硬碟讀回來,因此如果在內存整理後沒有用完所有新釋放的內存,這些額外的工作就毫無意義,只會拖慢速度。


糾正一下崔巍的一個錯誤吧

操作系統在內存不足時的換頁是根據有沒有dirty標記進行的,首先被換出的是非臟頁,內存管理演算法盡量保證被調出的頁不再被需要(即想辦法盡量晚得觸發page fault)。非臟頁即物理內存中沒有修改過因此在硬碟上可以找到的頁,換出的方式是直接標記為可用,通常換出後會用0覆蓋(為了安全性,而且並沒有損失多少性能)

顯然,進程的代碼段,進程以ro的方式打開的文件,都一定是不髒的。操作系統的文件緩存區(被關閉的文件)是不髒的,操作系統的寫入緩衝是髒的,但是寫入緩衝通常是預先為文件系統驅動程序分配的專用內存區域,人家是內核數據區。

也就是說,文件緩存 先於 進程非臟頁 先於 進程臟頁 被換出


我來嘗試著舉一個通俗點的例子吧。

電腦的內存就是市中心,原本大家工作得不亦樂乎。但市中心的地方終究是有限的,人多了總會住不下(內存不足),所以,那些最近不工作(不被使用)的就會搬到偏遠的地方(硬碟上的頁面文件)去住,反正不工作,住哪都一樣。

現在清理軟體來了,為了營造出都市很空曠閑適的感覺(內心很充足的錯覺),就派了大批無關人士進來,把大家都趕了出去(內存移到頁面文件)。

眼瞅著人都搬的差不多了(正在工作的總不能搬家),這些無關人士又憑空消失了(釋放內存),所以城市就空曠了起來。

當然還有一種辦法是直接關閉沒什麼卵用的公司(關閉無用程序),這樣公司的員工就會消失從而騰出位置了。不過事實上並沒有那麼多不幹正事的公司。

問題是,搬走的人可能只是休假一兩天,馬上就要回來工作。而連接市中心和邊緣地區的交通是很差的(內存速度遠高於硬碟),所以搬家就造成了交通堵塞,反而讓大家上班遲到了!生產效率也下降了!

嗯,就是這樣。

寫於堵在路上的一輛從山裡開往城裡的公交車上。


內存整理是利用Windows提供的API將不常用的內存頁換到虛擬內存。

沒啥用,特別是你內存夠大的時候。

至於結束進程的,更沒啥用。


這和計算機原理一點關係都沒有,加速球轉兩圈,給你個心理暗示,覺得系統快了,就這樣。清掉內存里的其他軟體後台運行的緩存,下次打開可能還會更慢,你沒有感覺,這也是心理因素。

你會感覺內存佔用多了電腦會慢,然而真的會嗎?上周我配虛擬機,不小心給虛擬機分配了系統剩下的所有內存,開著vs寫代碼,然而一點也不卡


閱讀一下 EmptyWorkingSet 這個api的文檔


內存不夠用就買買買 清理只是搶了別人的遲早要還回去


心理作用?反正只能在卡頓的時候釋放一些內存,好像還會回來的…最近我棒加了一條內存條…


實現方式上, @叛逆者提到的是一種方法,但是其實這種方法用的反而特別少。

更多的是 @tishion 提到的 EmptyWorkingSet 以及效果等價的 SetProcessWorkingSetSize(Ex);這倆API都接受一個 process handle,所以只要遍歷一遍進程列表然後call一遍API就行了....

對了,N年前國內一些流行的應用程序最喜歡的就是設定一個Timer然後不斷的調用SetProcessWokingSetSize,製造出佔用內存非常小的假象。


走題吐個槽,因為windows 7 的內存管理簡直就是渣。

16G內存隨便用用,空閑就變成0了,用rammap查看,大多數都被文件緩存佔用了,這還算合理。

不合理的是,之後啟動程序就奇慢無比,清理緩存慢也就算了,竟然不知道預測最近的分配量。最次最次始終保留1G的空閑內存不給緩存用啊

所以這時候我一般用rammap清理一下,整個世界頓時就清凈了。。。


推薦閱讀:

Windows XP 進程 PID 的範圍?為什麼會出現特別大的 PID?
為什麼微軟不對桌面軟體制定嚴格性能要求?
lumia950xl實際使用體驗如何?
Windows Phone 到底爽在哪裡?
為什麼 MacType 這種「邪魔歪道」的軟體會出現併流行?

TAG:MicrosoftWindows | 內存管理 |