Win API 內存整理


記得我的筆記本上曾經安裝了一款名為內存整理大師的軟件,當時覺得挺好用而且挺NB的,就是導致開機啟動有點慢。

當時我就在想,內存整理是怎么實現的?不過那是水平實在是不怎么樣,估計連windows程序的消息概念都不清楚吧。所以雖然不明白原因,但是覺得,很NB。

今天看到網上有關於EmptyWorkingSet函數的介紹,然后就看了下。看那幾個函數的調用,不是很明白,所以直接去MSDN查看函數原型以及介紹。

看明白了那兩個函數,就突然覺得,實現內存整理太簡單了……

首先擺出來幾個API函數,分別是:

EnumProcess http://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx

OpenProcess http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx

SetProcessWorkingSetSize http://msdn.microsoft.com/en-us/library/windows/desktop/ms686234(v=vs.85).aspx

EmptyWorkingSet http://msdn.microsoft.com/en-us/library/windows/desktop/ms682606(v=vs.85).aspx

看原型,點連接……

其中第一個函數的作用,就是枚舉全部的運行中進程,將其所有的進程ID放入到一個數組中。

第二個函數的作用,是根據進城ID獲取到進程句柄。這里需要提一點的就是,在其flag標志位中需要特別設置

第三個函數的作用,設置此進程的工作集大小。

第四個函數的作用,清理指定進程工作集中未使用的頁。

這里涉及一個概念,就是工作集。什么是工作集呢?其實最簡單的理解,就是進程一映射到物理內存的部分。

這個概念的出現,是因為如果把一個進程的全部代碼和資源都映射到內存中,必然存在很大的浪費,畢竟一個程序的執行代碼使用率不是均等的。把使用率高的代碼和資源映射到內存,把使用率低的代碼調到虛擬從內存中顯然是很明智的選擇。我就理解到這啦,如果理解有誤,歡迎更正。

所以步驟如下:

1調用 EnumProcess 函數獲取進程ID列表

2做一個循環,對其進行如下訪問:

2.1調用OpenProcess函數以PROCESS_SET_QUOTA權限打開進程句柄。

2.2調用SetProcessWorkingSetSize函數來對指定進程的工作集進行緊縮,后兩個參數只均為-1,盡可能空余出來未使用的頁(page)。

2.3調用EmptyWorkingSet函數來清除進程中未使用的頁

2.4關閉句柄

3 完成

簡單的很是吧?沒錯,就是這么簡單。

所以現在對於當時的那個什么內存管理大師特別不屑一顧,還好意思說大師……那可真是遍地都是大師了。

運行效果如下:

整理前:

整理后:

簡單整理一下代碼,貼下來如下:

 1 #include <windows.h>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <Psapi.h>
 5 #include <TlHelp32.h>
 6 #include <assert.h>
 7 #pragma comment(lib, "Iphlpapi")
 8 #pragma comment(lib, "Psapi")
 9 
10 int _tmain(int argc, _TCHAR* argv[])
11 {
12     DWORD pdwPIDArray[512];
13     TCHAR StrBuf[128];
14     DWORD dwPIDArraySize;
15     EnumProcesses(pdwPIDArray, 512, &dwPIDArraySize);
16     for(int i = 0; i < dwPIDArraySize; ++ i)
17     {
18         HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_SET_QUOTA, 0, pdwPIDArray[i]);
19         SetProcessWorkingSetSize(hProcess, -1, -1);
20         EmptyWorkingSet(hProcess);
21         CloseHandle(hProcess);
22     }
23     system("pause");
24     return 0;
25 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM