找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 6390|回复: 5

[开源] 所谓的内存释放工具——原理

 火.. [复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2011-6-20 22:01:16 | 显示全部楼层 |阅读模式
刚才逆向了一个内存释放的小工具,原来是调用了SetProcessWorkingSetSize()函数,MSDN一下。

此函数原型如下:

BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);
hProcess是进程的句柄,dwMinimumWorkingSetSize和dwMaximumWorkingSetSize分别是设置程序运行空间的最小和最大空间。

其实这个函数的功能就是保留一些必要的代码在内存中运行,其余的直接扔虚拟内存里去了。所谓虚拟内存,其实就是硬盘中划分出来的一片区域用来作内存使用。不过,这个只是暂时性地放进虚拟内存里,一旦程序激活了,内存又会被重新占用。其实这个特性操作系统本身就有的,可以先打开任务管理器,观察某个进程,如果将其窗口最小化后,所占用内存一下子就减小了;一旦被激活,又要开始重新对内存进行占用,这就是所谓的后台运行。

所以事实上并没有节约多少内存,一切都是骗眼睛的,这样做反而增加了内存与硬盘的页面交换频率,硬盘的针就转得更快了,有时反而更降低系统的性能。

贴一段代码:

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
/*
SetProcessWorkingSetSize函数演示
*/
int main()
{
    PROCESSENTRY32 pentry = {sizeof(pentry)};              //填充大小
    HANDLE hPSnap =::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //建立快照
    BOOL bMore = ::Process32First(hPSnap,&pentry);     //得到首个进程

    //循环搜索
    while(bMore)
    {
        if(strcmp("QQ.exe",pentry.szExeFile) == NULL)        //搜索QQ.exe这个进程
        {
            //如果找到,就用OpenProcess获得它的句柄
            //根据MSDN对SetProcessWorkingSetSize的描述,进程必须有PROCESS_SET_QUOTA权限
            HANDLE hProcess = ::OpenProcess(PROCESS_SET_QUOTA,
                                        FALSE,
                                        pentry.th32ProcessID);
        //hProcess不为空就表明获得了句柄值
        if(hProcess != NULL)
            //调用SetProcessWorkingSetSize函数
            ::SetProcessWorkingSetSize(hProcess, -1, -1);
        else
            break;
        }
        bMore = ::Process32Next(hPSnap,&pentry); //获得下一个进程
    }

    ::CloseHandle(hPSnap);   //关闭句柄
    return 0;
}

这段代码演示了对QQ进程(QQ.exe)的进程释放。首先建立一个进程快照,然后开始搜索QQ.exe这个进程,如果找到了就打开它的句柄,然后进行内存释放。
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

47

主题

265

回帖

8

精华

核心会员

积分
10349
发表于 2011-6-20 22:34:02 | 显示全部楼层
本帖最后由 ywledoc 于 2011-6-20 22:34 编辑

跟所谓的内存整理软件差不多~
申请一大堆内存~再free掉~
赤果果的欺骗~

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-6-20 23:04:41 | 显示全部楼层
没有任何用的东西,都是骗人的。。。

0

主题

55

回帖

0

精华

铜牌会员

积分
177
发表于 2011-11-29 09:57:39 | 显示全部楼层
经过实验测试,正如楼主所说的那样。

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2011-12-2 15:11:50 | 显示全部楼层
这个函数的用法并不是所谓的"释放内存",而是让程序在后台工作时尽量把本进程的物理内存占用控制在某一范围,以给别的进程让出物理内存.

实际的逻辑内存占用并没减少,只是被尽量地使用了虚拟内存而已.

这在程序最小化,隐藏主界面,转入后台工作等时刻调用是最合适的,但也不是拼了老命地调用,而是调用一次即可.

所以网上太多错误的思路了.
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2011-12-2 15:18:02 | 显示全部楼层
以前的内存整理软件原理不是这样,而是在自己进程申请一片巨大的物理内存,然后由于这个申请到的物理内存很大,系统为了给当前进程腾出这么多的物理内存,就不得不把其它非当前进程的物理内存占用数减少,也就是将位于物理内存中的数据转移到虚拟内存中,效果与这个SetProcessWorkingSetSize差不多.

最终的结果就是物理内存未被使用的值非常大,但是一旦切换到别的进程中,会发觉硬盘狂闪,并且那个进程会无响应一会儿,时间长短与写入到虚拟内存中的内容的大小有关.

我个人认为,使用这个API对进程设置指定大小的物理内存占用量才是比较合理的用法.
我就是嗷嗷叫的老马了......

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表