VC使用EmptyWorkingSet()來清理內存

    360安全衛士有清理內存的工具,qq管家卻沒有,不過爲了qq升級~唉只好用qq管家,可是電腦總休眠就會造成內存佔用過多,甚至90%多,電腦運行速度直線下降,所以想自己寫個小工具清理下內存,根據以前用超級兔子的經驗,大概有兩種清理內存的方案,一種是快速清理,一種是深度清理。根據網上找到的資料:

http://hi.baidu.com/xuzhhua/blog/item/05dfa34ac9008ef582025cd2.html

    並且實踐了一下,快速清理內存還是有效果的。
EmptyWorkingSet msdn上的說明如下:

Removes as many pages as possible from the working set of the specified process.
Syntax
BOOL WINAPI EmptyWorkingSet(
__in HANDLE hProcess
);
Parameters
hProcess [in]
A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right and the PROCESS_SET_QUOTA access right. For more information, see Process Security and Access Rights.
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.


SetProcessWorkingSetSize msdn的說明如下:

Sets the minimum and maximum working set sizes for the specified process.
Syntax
BOOL WINAPI SetProcessWorkingSetSize(
__in HANDLE hProcess,
__in SIZE_T dwMinimumWorkingSetSize,
__in SIZE_T dwMaximumWorkingSetSize
);
If both dwMinimumWorkingSetSize and dwMaximumWorkingSetSize have the value (SIZE_T)–1, the function removes as many pages as possible from the working set of the specified process.



    所以SetProcessWorkingSetSize 將兩個參數設爲-1 與EmptyWorkingSet 功能看起來是一樣的,返回值和EmptyWorkingSet 代表的含義一樣
可以附加返回值判斷是否不爲0來確定是否清理成功。
下面是快速清理的源碼

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
using namespace std;
#pragma comment (lib,"psapi.lib")
void AdjustTokenPrivilegesForNT()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
 
    // Get a token for this process.
 
    OpenProcessToken(GetCurrentProcess(),
                     TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
 
    // Get the LUID for the EmptyWorkingSet privilege.
 
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
 
    tkp.PrivilegeCount = 1; // one privilege to set
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
    // Get the EmptyWorkingSet privilege for this process.
 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
}
 
BOOL EmptyAllSet()
{
    HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(SnapShot==NULL)
    {
        cout<<"snapshot==null"<<endl;
        return FALSE;
    }
    PROCESSENTRY32 ProcessInfo;//聲明進程信息變量
    ProcessInfo.dwSize=sizeof(ProcessInfo);//設置ProcessInfo的大小
    int count = 0;
    //返回系統中第一個進程的信息
    BOOL Status=Process32First(SnapShot, &ProcessInfo);
    cout<<"status="<<Status<<endl;
    while(Status)
    {
        cout<<"processID="<<ProcessInfo.th32ProcessID<<endl;
        count ++;
        HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,
                                  ProcessInfo.th32ProcessID);
        if(hProcess)
        {
            cout<<"begin clean Memory"<<endl;
            SetProcessWorkingSetSize(hProcess,-1,-1);
            //內存整理
            EmptyWorkingSet(hProcess);
            CloseHandle(hProcess);
        }
        //獲取下一個進程的信息
        Status=Process32Next(SnapShot,&ProcessInfo);
    }
    cout << "total:" << count+1 << " processes"<<endl;
    cout<<"end"<<endl;
    return TRUE;
}

    其中BOOL EmptyAllSet()函數就是快速清理內存的函數,AdjustTokenPrivilegesForNT()據說是提升權限以便可以清理其他進程的,不過我在win7下沒有發現作用,也許是我用的是管理員賬戶

    另外還有深度整理,通過資源的查詢以及個人對超級兔子深度整理的現象的解讀:超級兔子進行深度整理的時候磁盤讀寫會變多,cpu消耗變大,內存佔用會增加到100%,然後突然釋放。所以我覺得深度整理應該是不停的new一塊大內存,知道內存爆滿,使操作系統將內存中的數據交換到虛擬內存磁盤中,以後想運行某個程序再從交換數據到內存中,以此達到清理內存中無用數據的效果。代碼如下:

void deepClean()
{
    const int num = 1000;
    int size = 500000;
    int *a[num];
    cout << "begin deepclean" << endl;
    for(int i = 0 ; i < num; i++)
    {
        a[i] = new int[size];
    }
    cout << "new over" << endl;
    for(int i = 0 ; i < num; i++)
    {
        delete a[i];
    }
    cout << "end deepclean" << endl;
}

    我寫的代碼比較簡單,也沒有考慮太多,按照int型有4字節考慮,new一個500000的int數字相當於申請的一個2m的堆空間,1000次就是2g,我內存是3g,我只是覺得或許差不多,沒敢申請4g去,可以再試試。我寫的深度整理貌似是有效果的,整理前後物理內存佔用的確變低了,但是有2個問題:第一是深度整理期間時間較長,卡住,和超級兔子類似,第二是整理之後系統會偏慢一會,因爲操作系統經過這個大清洗:)大量數據都到磁盤上的話會影響運行的性能,不過慢慢緩過來就好了,至少清理物理內存的效果是達到了。我理解的快速清理的原理是將進程的數據as many as的清理,而深度清理的原理則是通過申請大塊內存以迫使操作系統將內存中的數據交換到磁盤上,以後使用再交換回來,所以纔會有看到的現象。深度清理效果可能會很好,但是體驗很不好,尤其使用的時候不輕量。

因爲我對vc和windows的庫函數並不熟
對以上使用的函數進行一些資料查找:

CreateToolhelp32Snapshot
Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
Syntax
HANDLE WINAPI CreateToolhelp32Snapshot(
__in DWORD dwFlags,
__in DWORD th32ProcessID
);

開發完畢,工具下載鏈接  http://download.csdn.net/detail/u013207660/6833437


工具截圖,安全無毒啊,我每臺機器上都用,用了幾年,沒有什麼崩潰啊什麼的。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章