倍可親

回復: 1
列印 上一主題 下一主題

揭穿內存佔用極低軟體的詭計

[複製鏈接]

1萬

主題

1萬

帖子

1萬

積分

八級貝殼核心

倍可親終生會員(廿一級)

Rank: 5Rank: 5

積分
18033
跳轉到指定樓層
樓主
kent 發表於 2006-11-10 08:21 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
 物理內存和虛擬內存

  物理內存,在應用中,自然是顧名思義,物理上,真實的插在板子上的內存是多大就是多大了.看機器配置的時候,看的就是這個物理內存.

  如果執行的程序很大或很多,就會導致物理內存消耗殆盡.為了解決這個問題,Windows中運用了虛擬內存技術,即拿出一部分硬碟空間來充當內存使用,當內存佔用完時,電腦就會自動調用硬碟來充當內存,以緩解內存的緊張.

  一個程序,不可避免地要用到虛擬內存,因為不頻繁執行或者已經很久沒有執行的代碼,沒有必要留在物理內存中,只會造成浪費;放在虛擬內存中,等執行這部分代碼的時候,再調出來.

  Windows 的任務管理器可以幫助我們看到進程的虛擬內存.調出任務管理器,點擊菜單「查看」-「選擇列」,在出現的窗口中,鉤上「虛擬內存大小」,如圖1: 

  

  點「確定」,這個時候,進程列表中已經顯示各進程的虛擬內存大小,如圖2:

  

  一個程序到底應該使用多少虛擬內存呢?不一定,但是應該以恰到好處的符合虛擬內存原本作用為最好.

  下面將揭穿表面看起來調用了大量圖片、大量運行庫的程序,為什麼才「佔用」不到 1 MB 的內存的詭計.

  原來是 SetProcessWorkingSetSize 函數

  MSDN 對該函數的表述(翻譯):使用這個函數來設置應用程序最小和最大的運行空間,只會保留需要的內存.當應用程序被閑置或系統內存太低時,操作系統會自動調用這個機制來設置應用程序的內存.應用程序也可以使用 VirtualLock 來鎖住一定範圍的內存不被系統釋放;當你加大運行空間給應用程序,你能夠得到的物理內存取決於系統,這會造成其他應用程序降低性能或系統總體降低性能,這也可能導致請求物理內存的操作失敗,例如:建立 進程,線程,內核池,就必須小心的使用該函數.

  也就是說,該函數不是節省內存,而是強制把進程的物理內存搬到虛擬內存中.

  另外有一些資料上說,該函數「將有可能導致缺頁中斷,嚴重影響性能」.

  函數原型:

  BOOL SetProcessWorkingSetSize(

  HANDLE hProcess,

  SIZE_T dwMinimumWorkingSetSize,

  SIZE_T dwMaximumWorkingSetSize

  );

  我們用 VB 來做這麼一個簡單的例子,是程序佔用 300 KB 內存吧.

  建立一個標準的 VB 工程,在 Form1 中放置一個 Timer1 ,把 Interval 屬性設置為 1000 (即 1 秒).然後在代碼編輯框中輸入以下代碼:

  Private Declare Function SetProcessWorkingSetSize Lib "kernel32" (ByVal hProcess As Long, ByVal dwMinimumWorkingSetSize As Long, ByVal dwMaximumWorkingSetSize As Long) As Long

  Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

  Private Sub Timer1_Timer()

  SetProcessWorkingSetSize GetCurrentProcess(), 50000, 100000

  End Sub

  然後生成 工程1.exe,執行,調出任務管理器查看,發現內存佔用才 320 KB.如果把定時器關閉,這進程的內存一般 4 MB左右.

  必須定時執行該函數,否則虛擬內存會慢慢被調出來,恢復原來的內存大小.

  如果要使一個本來需要佔用大量內存的程序減低到幾百 KB ,使用同樣的方法即可.

  詭計帶來的危害

  如果 SetProcessWorkingSetSize 函數被正常使用,是非常有用處的.但是為了矇騙用戶的眼睛,每秒,甚至幾十毫秒就把大量內存往虛擬內存裡面壓,就會帶來無可預計的危害.看看這篇文章怎麼說:「因為他只是暫時的將應用程序佔用的內存移至虛擬內存,一旦,應用程序被激活或者有操作請求時,這些內存又會被重新佔用.如果你強制使用該方法來設置程序佔用的內存,那麼可能在一定程度上反而會降低系統性能,因為系統需要頻繁的進行內存和硬碟間的頁面交換.」.

  沒錯,如果你使用了這類軟體,意味著你的硬碟將每秒將 I/O 大量數據;硬碟的磁針將拚命旋轉...(當然硬碟磁針不可能不旋轉^_^,只是選擇得更厲害而已).

  不是說 BT 很傷內存嗎?不然,因為現在大多 BT 軟體都有緩存技術.且看 Bitcomet 官方對緩存技術的說明:「傳統BT高速下載時硬碟會響得很厲害,這是大量的隨機讀取造成的.... BitComet可以由用戶設置緩存大小.... 可以明顯地看出犧牲一小部分內存作緩存對硬碟的保護作用.」

  是不是有種心寒的感覺?一類軟體寧願犧牲內存,也要減少保護硬碟;而另外一類軟體,卻為了欺騙用戶,讓CPU、硬碟更加奔波......

  抓一個兇手

  這類軟體不少,我以其中一個桌面工具為例,揭穿它的假面具(不點名字了).運行該軟體后,隨意操作一下,然後打開進程管理器,把虛擬內存列調出來,找到該進程,如圖3:

  

  OK,20 MB 虛擬內存,而只有 632 KB 物理內存.細心的你會發現,大概每 1 秒,該行都有閃爍的感覺,沒錯,這正是每秒調用 SetProcessWorkingSetSize 的結果.另外,我們打開 Norton Process Viewer ,查看該進程的 CPU 佔用情況. 

  可以看到,就算沒有操作該軟體,但是每秒,都有 3% 的CPU佔用起伏(雖然這並不能說明什麼).另外,內存框中可以看到物理內存和虛擬內存的佔用,兩者相去甚遠.此外,可以用 Hook API 技術來證明每秒調用 SetProcessWorkingSetSize 的行為.

  應該怎麼做

  這篇文章只想讓用戶了解軟體佔用資源的實際.而程序員應該把下功夫,真正從代碼中減少內存的消耗,而不是一味忽悠用戶.調用 SetProcessWorkingSetSize 會帶來某些好處,但是何時調用、如何調用應該符合兩個要求:

  1,在程序暫時不被使用的時候(例如最小化);

  2,物理內存和虛擬內存應處於一個合適的比例(而不是 600 KB 比 20 MB 這麼荒唐);

  3,或者不調用,讓 Windows 去處理.

1

主題

53

帖子

13

積分

註冊會員

初過語言關(三級)

Rank: 1

積分
13
沙發
rafale 發表於 2006-11-11 00:00 | 只看該作者
謝謝Kent!
回復 支持 反對

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 註冊

本版積分規則

關於本站 | 隱私權政策 | 免責條款 | 版權聲明 | 聯絡我們

Copyright © 2001-2013 海外華人中文門戶:倍可親 (http://big5.backchina.com) All Rights Reserved.

程序系統基於 Discuz! X3.1 商業版 優化 Discuz! © 2001-2013 Comsenz Inc.

本站時間採用京港台時間 GMT+8, 2025-8-23 16:03

快速回復 返回頂部 返回列表