首页
社区
课程
招聘
[求助]清理内存垃圾是如何实现的??
发表于: 2013-10-6 23:28 17584

[求助]清理内存垃圾是如何实现的??

2013-10-6 23:28
17584
想自己写一个   清理内存垃圾/优化内存   的程序,比如360的加速器。
用 C/C++ 该怎么实现?
请大侠指点思路。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (21)
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
2
遍历进程handle

GetProcessWorkingSetSize(handle,&oldsize1,&oldsize2);
SetProcessWorkingSetSize(handle,-1,-1);
SetProcessWorkingSetSize(handle,oldsize1,oldsize2);

360的内存清理 不仅使用内存回收技术!而且通过进程规则 把不需要的进程和服务给关闭掉!
2013-10-7 04:38
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
又***见到清理工作集来释放内存的人了
说了多少次这方法没意义还****用
2013-10-7 05:43
0
雪    币: 255
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习一下
2013-10-7 09:13
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
自欺欺人而已,没有用。
2013-10-7 09:53
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
6
第一 语言粗俗就表示你很NB!
第二 该函数是将占用物理内存空间转到虚拟内存上!
     看我的写法
    GetProcessWorkingSetSize(handle,&oldsize1,&oldsize2);
      SetProcessWorkingSetSize(handle,-1,-1);
      SetProcessWorkingSetSize(handle,oldsize1,oldsize2);
这样写完!所有进程重新按需分配物理内存 未活动进程空间仍然留在虚拟内存上!这样程序既不卡!也能回收物理内存

第三 这是个技术讨论贴!你这么激动做什么?要是人人都像你这样?看见自己不爽的API就开骂,谁还敢在论坛回帖讨论?

所以 不好意思说你什么了
2013-10-7 10:31
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
7
单独使用SetProcessWorkingSetSize(handle,-1,-1); 或者对单一活动进程使用的却没什么实际意义!
2013-10-7 10:33
0
雪    币: 81
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
没使用过这些 对于配置比较低的电脑还是有些用处的。
2013-10-7 10:40
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
目测大家都很牛,也不要骂了,都是来学习的。
但是还得厚着脸皮问楼主要完整代码……Thanks!
2013-10-7 11:59
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
第一,******是一个不雅的汉语口语词汇

第二,一个人的语言很粗俗和一个人很牛屄之间不仅没有逻辑关系更没有统计关系。谁否定这点他要么没逻辑要么没文化看不懂文章

第三,****************************************************************************************************,**************

第四,你其实是在说:“我信用卡欠一万块钱,我借高利贷还了这一万,现在我不欠任何钱了。”
SetProcessWorkingSetSize(hProcess, -1, -1)只是将内存中的页面移动到硬盘上的页面文件,我没想到你竟然知道这点后还这么做。这个函数没有释放任何内存,所以被占据的内存地址依然被占据着,纵使他们现在不占用内存实际物理页面,换言之一个32位程序用尽了它自己的2G地址空间后,你“释放内存”后它依然不能分配任何新内存。
更何况这个函数是将所有目前没用到的内存页面全部移出,无论他们是代码是变量是常量是资源是一分钟内59秒每秒访问一亿次就你执行的这一秒没访问还是一个被泄露的内存,他们统统都要滚蛋。内存页面是滚蛋了,但是程序对这些数据的需求没有滚蛋,所以系统又要把页面从硬盘再挪出来。就这样你还好意思说“这样程序既不卡”?而且随着时间的推移,所有非泄漏内存都会被程序访问(这就是内存泄漏的定义啊),也就是说所有被你移出去的内存页面最终还是要一个不落的回到内存里面去。写到这里,我真想替系统和被你清理的程序们对你说一句:******。

第五,由于这也不能说那也不能说,我决定引用知名Linux内核开发者Linus Torvalds的原话好了:“RTFSC”你不说也就罢了,还特意补充解释一下你的高明之处,真是张口就错。按照MSDN上的解释,-1(除了它的特殊作用以外)对于dwMinimumWorkingSetSize和dwMaximumWorkingSetSize来说是一个无效的大小:

(dwMinimumWorkingSetSize)This parameter must be greater than zero but less than or equal to the maximum working set size.
(dwMaximumWorkingSetSize)This parameter must be greater than or equal to 13 pages (for example, 53,248 on systems with a 4K page size), and less than the system-wide maximum (number of available pages minus 512 pages).

既然如此,只要两个参数都是-1,Windows将永远不会修改工作集的大小,因为那根本就是个不合法的大小。你的备份恢复简直就是画蛇添足纯属多余。

最后,我其实不是对API不爽,我是对你不爽。API是无罪的,但你知道你在干什么么?你是在误人子弟!你可知道,如果我不站出来指出你的荒谬之处,就很有可能有一个没法升级电脑的小学生为了玩LOL而用了你的代码,而很有可能导致他爸爸的Word程序因为内存不足而崩溃,而很有可能导致重要的医疗器械的技术文档消失,而很有可能导致工厂不能按时生产出需要的器械,而很有可能导致在医院的一个小妹妹因为得不到治疗而死,而很有可能导致他哥哥冲冠一怒打死了主刀医生,而很有可能导致医生背后的黑暗组织以为是敌人的行动,而很有可能导致他们对二炮部队发动恐怖袭击,而很有可能导致二炮部队的应急程序启动使用东风洗地,而很有可能导致全球核战,而很有可能导致外星人注意到了核弹的辐射,而很有可能导致外星人使用二相箔对宇宙进行降维打击,而很有可能导致宇宙的灭亡。一想到你的所作所为会有如此可怕的后果,作为一个有良知有爱心有道德有血性的中国人怎能不激动?怎能不站出来制止你的所作所为?是中国人就转!
2013-10-8 06:23
0
雪    币: 211
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这。。操作系统自己都不知道某个程序申请的内存能不能干掉,怎么可能让内核去释放啊
2013-10-8 08:38
0
雪    币: 755
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
潜水这么久,不得不说, 誓言剑,你这样子在论坛胡作非为,除了让更多人沉默以对别人的问题,还能有什么好处?

现在windows的软件优化内存,哪个不是使用 SetProcessWorkingSetSize

正如楼上所说,连操作系统都不知道这申请的内存能不能释放,也只能用SetProcessWorkingSetSize

如果你有更好的解决办法,请拿出来,而不是在冷嘲热讽

看到坛主编辑你的回复没? "勿让他人感到不适",

你后面又扯什么 ,玩LOL而用了你的代码,二炮部队,恐怖袭击,宇宙的灭亡 ,是为了形容你思维混乱吗?

你扯了这么多,扯到了一点解决办法没?

你的最后一句话 "是中国人就转!" 暴露了你恶毒的本质

如果你没有18岁,只当你年少无知.

如果你年满18岁,请不要放弃治疗!

最后借用你的话,如果是真正的 "有良知有爱心有道德有血性的中国人" , 只会希望像 "誓言剑"这样的人越来越少,
bujin888 越来越多的多! 这样世界才会更美好!
2013-10-8 11:45
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
13
谁说-1无效的? 在这个函数中-1和0xFFFFFFFF是等效的!其次在win7 ring3层没看见说-1 无效 只有为0时才无效

BOOL __stdcall SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize)
{
  return SetProcessWorkingSetSizeEx(hProcess, dwMinimumWorkingSetSize, dwMaximumWorkingSetSize, 0);
}

BOOL __stdcall SetProcessWorkingSetSizeEx(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize, DWORD Flags)
{
  int v4; // edi@3
  signed int v5; // esi@3
  int ProcessInformation; // [sp+8h] [bp-40h]@1
  char Dst; // [sp+Ch] [bp-3Ch]@1
  SIZE_T v9; // [sp+10h] [bp-38h]@3
  SIZE_T v10; // [sp+14h] [bp-34h]@3
  DWORD v11; // [sp+38h] [bp-10h]@3
  int v12; // [sp+40h] [bp-8h]@1
  int v13; // [sp+44h] [bp-4h]@1
  bool dwMinimumWorkingSetSizea; // [sp+54h] [bp+Ch]@3

  v12 = 33;
  v13 = 14;
  ProcessInformation = 0;
  memset(&Dst, 0, 0x34u);
  if ( dwMinimumWorkingSetSize && dwMaximumWorkingSetSize )
  {
    v10 = dwMaximumWorkingSetSize;
    v11 = Flags;
    v9 = dwMinimumWorkingSetSize;
    v4 = RtlAcquirePrivilege(&v12, 2, 0, &dwMaximumWorkingSetSize);
    v5 = NtSetInformationProcess(hProcess, ProcessQuotaLimits, &ProcessInformation, 0x38u);
    dwMinimumWorkingSetSizea = v5 >= 0;
    if ( v4 >= 0 )
    {
      RtlReleasePrivilege(dwMaximumWorkingSetSize);
      dwMaximumWorkingSetSize = 0;
    }
  }
  else
  {
    v5 = -1073741811;
    dwMinimumWorkingSetSizea = 0;
  }
  if ( !dwMinimumWorkingSetSizea )
    BaseSetLastNTError(v5);
  return dwMinimumWorkingSetSizea;
}



内核中也没看见
        case ProcessQuotaLimits:

            Length = sizeof(QUOTA_LIMITS);
            if (ProcessInformationLength != Length)
            {
                Status = STATUS_INFO_LENGTH_MISMATCH;
                break;
            }

            Status = ObReferenceObjectByHandle(ProcessHandle,
                                               PROCESS_QUERY_INFORMATION,
                                               PsProcessType,
                                               PreviousMode,
                                               (PVOID*)&Process,
                                               NULL);
            if (!NT_SUCCESS(Status)) break;


            Status = STATUS_SUCCESS;

            _SEH2_TRY
            {

                QuotaLimits->MaximumWorkingSetSize =
                        Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
                QuotaLimits->MinimumWorkingSetSize =
                        Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;


                QuotaLimits->TimeLimit.LowPart = MAXULONG;
                QuotaLimits->TimeLimit.HighPart = MAXULONG;


                if (Process->QuotaBlock == &PspDefaultQuotaBlock)
                {
                    QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
                    QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
                    QuotaLimits->PagefileLimit = (SIZE_T)-1;
                }
                else
                {
                    QuotaLimits->PagedPoolLimit =
                        Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
                    QuotaLimits->NonPagedPoolLimit =
                        Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
                    QuotaLimits->PagefileLimit =
                        Process->QuotaBlock->QuotaEntry[2].Limit;
                }
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                Status = _SEH2_GetExceptionCode();
            }
            _SEH2_END;
2013-10-8 17:39
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
求放有意义的出来
2013-10-8 17:59
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
15
同求
2013-10-8 18:05
0
雪    币: 219
活跃值: (778)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
16
我支持你的 求放出
2013-10-8 18:25
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
再买一根内存条……
这种做法的确是没意义的
2013-10-8 18:31
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
[QUOTE=bujin888;1228863]
谁说-1无效的? 在这个函数中-1和0xFFFFFFFF是等效的!其次在win7 ring3层没看见说-1 无效 只有为0时才无效

BOOL __stdcall SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize)
{
  return SetProcessWorkingSetSizeEx(hProcess, dwMinimumWorkingSetSize, dwMaximumWorkingSetSize, 0);
}

BOOL __stdcall SetProcessWorkingSetSizeEx(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize, DWORD Flags)
{
  int v4; // edi@3
  signed int v5; // esi@3
  int ProcessInformation; // [sp+8h] [bp-40h]@1
  char Dst; // [sp+Ch] [bp-3Ch]@1
  SIZE_T v9; // [sp+10h] [bp-38h]@3
  SIZE_T v10; // [sp+14h] [bp-34h]@3
  DWORD v11; // [sp+38h] [bp-10h]@3
  int v12; // [sp+40h] [bp-8h]@1
  int v13; // [sp+44h] [bp-4h]@1
  bool dwMinimumWorkingSetSizea; // [sp+54h] [bp+Ch]@3

  v12 = 33;
  v13 = 14;
  ProcessInformation = 0;
  memset(&Dst, 0, 0x34u);
  if ( dwMinimumWorkingSetSize && dwMaximumWorkingSetSize )
  {
    v10 = dwMaximumWorkingSetSize;
    v11 = Flags;
    v9 = dwMinimumWorkingSetSize;
    v4 = RtlAcquirePrivilege(&v12, 2, 0, &dwMaximumWorkingSetSize);
    v5 = NtSetInformationProcess(hProcess, ProcessQuotaLimits, &ProcessInformation, 0x38u);
    dwMinimumWorkingSetSizea = v5 >= 0;
    if ( v4 >= 0 )
    {
      RtlReleasePrivilege(dwMaximumWorkingSetSize);
      dwMaximumWorkingSetSize = 0;
    }
  }
  else
  {
    v5 = -1073741811;
    dwMinimumWorkingSetSizea = 0;
  }
  if ( !dwMinimumWorkingSetSizea )
    BaseSetLastNTError(v5);
  return dwMinimumWorkingSetSizea;
}
内核中也没看见

        case ProcessQuotaLimits:

            Length = sizeof(QUOTA_LIMITS);
            if (ProcessInformationLength != Length)
            {
                Status = STATUS_INFO_LENGTH_MISMATCH;
                break;
            }

            Status = ObReferenceObjectByHandle(ProcessHandle,
                                               PROCESS_QUERY_INFORMATION,
                                               PsProcessType,
                                               PreviousMode,
                                               (PVOID*)&Process,
                                               NULL);
            if (!NT_SUCCESS(Status)) break;

            Status = STATUS_SUCCESS;

            _SEH2_TRY
            {

                QuotaLimits->MaximumWorkingSetSize =
                        Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
                QuotaLimits->MinimumWorkingSetSize =
                        Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;

                QuotaLimits->TimeLimit.LowPart = MAXULONG;
                QuotaLimits->TimeLimit.HighPart = MAXULONG;

                if (Process->QuotaBlock == &PspDefaultQuotaBlock)
                {
                    QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
                    QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
                    QuotaLimits->PagefileLimit = (SIZE_T)-1;
                }
                else
                {
                    QuotaLimits->PagedPoolLimit =
                        Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
                    QuotaLimits->NonPagedPoolLimit =
                        Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
                    QuotaLimits->PagefileLimit =
                        Process->QuotaBlock->QuotaEntry[2].Limit;
                }
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                Status = _SEH2_GetExceptionCode();
            }
            _SEH2_END;
[/QUOTE]

#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
    SIZE_T min, max;
    GetProcessWorkingSetSize(GetCurrentProcess(), &min, &max);
    cout << min << "\t" << max << endl;
    if (!SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1))
    {
        cout << "failed";
    }
    else
    {
        GetProcessWorkingSetSize(GetCurrentProcess(), &min, &max);
        cout << min << "\t" << max << endl;
    }
}


另外你的代码是从ReactOS中提取出来的,不是Windows NT的实现

另外你的代码是NtQueryInformationProcess的片段,不是NtSetInformationProcess的片段,这真是哈哈哈哈.那么就让我给大家展示一下ReactOS的NtSetInformationProcess中对这个功能的实现吧!
case ProcessQuotaLimits:
            DPRINT1("Quota Limits not implemented\n");
            Status = STATUS_NOT_IMPLEMENTED;
            break;


关于具体实现大家可以自己去WRK的ps\psquery.c:1889(PspSetQuotaLimits)一探究竟
2013-10-8 23:13
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
清理内存,只有关闭程序一途
2013-10-8 23:14
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
现在windows的软件优化内存,哪个不是使用 SetProcessWorkingSetSize

大家都错你也跟着错?

如果你有更好的解决办法,请拿出来,而不是在冷嘲热讽

你扯了这么多,扯到了一点解决办法没?

你问这个问题就跟问我如何不工作也能赚钱一样,做梦.你要么省点花要么就给我去工作
对于内存,你要么关程序要么买,难道你还能有啥方法突破物理极限,制造出不存在的内存?
我想你既然在这里问如何清理内存,你肯定是不想买的,那么看来就只有关程序这一个办法咯?
[QUOTE=bujin888;1228285]
遍历进程handle

GetProcessWorkingSetSize(handle,&oldsize1,&oldsize2);
SetProcessWorkingSetSize(handle,-1,-1);
SetProcessWorkingSetSize(handle,oldsize1,oldsize2);

360的内存清理 不仅使用内存回收技术!而且通过进程规则 把不需要的进程和服务给关闭掉! [/QUOTE]
他2L都说过了我还再说一遍干啥?
2013-10-8 23:22
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
两天没来了,怎么这么吵。

补充下问题:
我电脑虚拟内存设置的是最小值 16M
  在任务管理器里面 一个进程 是占用了快 1G 的内存了,用360的加速球 ,一下子到 200多M
  那么多空间跑那里去了

大家不要吵了
2013-10-9 00:40
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
22
说白了,就是把那个进程的工作集剪裁了,同时也可能剪裁进程映射的文件的缓存。让你以为进程占用的内存变小了,直接看进程的virtual size,并不会有改变。这个方法是牺牲未来的性能,来让你“看着爽”,没有实际意义。

如果还不明白,建议先学下win的内存管理。
2013-10-11 02:45
0
游客
登录 | 注册 方可回帖
返回
//