SetProcessWorkingSetSize - 什么是捕获?

时间:2011-05-19 13:48:38

标签: delphi memory-management

我找到了article on About.com that tells you how you can manage your apps memory.

以下是代码:

procedure TrimAppMemorySize;
var
  MainHandle : THandle;
begin
  try
    MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID) ;
    SetProcessWorkingSetSize(MainHandle, $FFFFFFFF, $FFFFFFFF) ;
    CloseHandle(MainHandle) ;
    Log('Trimmed Memory Successfull!');
  except
    Log('Failed to trim Memory!');
  end;
  Application.ProcessMessages;
end;

我试了一下,效果很好 - 即使我的应用程序正在做某事,我点击按钮等等,它仍然可以做到这一点,它就像一个魅力。我在资源监视器中查看我的应用程序内存使用情况,据我所知,这一切都很好。

那么......捕获的是什么?我们都处理内存问题,但解决方案真的那么简单吗?谁能告诉我,如果每隔60秒这样做是件坏事?

我将重新启动并尝试运行我的程序,并发布我的资源监视器的屏幕截图。

4 个答案:

答案 0 :(得分:35)

是的,这是件坏事。你告诉操作系统你知道更多关于内存管理的事情,这可能不是真的。您告诉要将所有非活动内存分页到磁盘。它服从。当您再次触摸任何内存时,操作系统必须将其重新分页到RAM中。您正在强制实际上并不知道所需的磁盘I / O.

如果操作系统需要更多空闲内存,可以找出最近没有使用的内存并将其分页。这可能来自您的程序,也可能来自其他程序。但是如果操作系统需要更多的可用内存,那么你只需要强制一堆没有人要求的磁盘I / O.

如果你有你不知道的记忆,那就把它释放吧。不要只是将其分页到磁盘。如果您有操作系统认为您不需要的内存,它会在需要时自动为您分页。

此外,调用Application.ProcessMessages通常是不明智的,除非您知道您的主要线程需要处理的消息,否则它本身不会处理。当没有别的事情要做时,应用程序会自动处理消息,所以如果你无事可做,只需让应用程序自行运行。

答案 1 :(得分:6)

“catch”就是你刚刚告诉操作系统从工作集中删除实际在RAM中的页面。假设操作系统正在删除没有您将再次访问的数据的页面,则没有问题。但如果它正在分析您的流程将来需要的数据,那么您刚刚告诉Windows“请更多页面错误。”

这段代码的主要问题在于你为了系统的其他部分而牺牲自己的进程性能(虽然颠簸实际上损害了整个系统。)这有点高贵,但显然没有“抓住”自由

答案 2 :(得分:5)

这在道德上相当于假装操作系统,你的机器是RAM危机的永久状态。系统知道如何比你更好地管理它的内存,让它继续工作。

遗憾的是,当系统使用其所有RAM及其所有CPU时,人们会担心这是一个非常常见的错误。实际上,如果您的系统未能充分利用其资源,您应该担心!

答案 3 :(得分:-1)

实际上当使用GlobalAlloc / GlobalFree时,Windows确实倾向于将这些内存块保留在你的进程上,当我只使用40MB因为GlobalFrees没有真正释放内存时,我已经“看起来”正在使用400MB内存(只要机器正在运行,我们正在谈论在后台运行的过程)。在这种情况下,我发现能够告诉Windows压缩进程内存非常有用。我确实使用GetProcessMemoryInfo并检查当前的.WorkingSetSize,如果大于一定量(如100MB),则压缩内存。是的,这确实会导致正在使用的内存出现页面错误,但内存将被释放回内核以供其他进程使用。

因此,在某些情况下,我发现Windows没有做好“垃圾收集”和返回资源。很高兴这个电话可用,非常有用。