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


工具截图,安全无毒啊,我每台机器上都用,用了几年,没有什么崩溃啊什么的。




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