windows 使用 SetProcessWorkingSetSize 的利弊

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8292229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 18:32:32  来源:igfitidea点击:

Pros and Cons of using SetProcessWorkingSetSize

windowswinapimemory-managementprocess

提问by Shankar

I have an issue with memory management in my application. The application memory is growing up rapidly during the runtime. I'm using datasets in the disconnected mode. To overcome this issue, I'm flushing the DS frequently and also using SetProcessWorkingSetSizeto manage the memory usage. It's working fine in my development computer. What are the pros and cons of using SetProcessWorkingSetSize?

我的应用程序中存在内存管理问题。应用程序内存在运行时快速增长。我在断开连接模式下使用数据集。为了克服这个问题,我经常刷新 DS 并使用它SetProcessWorkingSetSize来管理内存使用情况。它在我的开发计算机上运行良好。使用的优缺点是SetProcessWorkingSetSize什么?

回答by Hans Passant

SetProcessWorkingSetSize() controls the amount of RAMthat your process uses, it doesn't otherwise have any affect on the virtual memory size of your process. Windows is already quite good at dynamically controlling this, swapping memory pages out on demand when another process needs RAM. By doing this manually, you slow down your program a lot, causing a lot of page faults when Windows is forced to swap the memory pages back in. SetProcessWorkingSetSize is typically used to increasethe amount of RAM allocated for a process. Or to force a trim when the app knows that it is going to be idle for a long time. Also done automatically by old Windows versions when you minimize the main window of the app.

SetProcessWorkingSetSize() 控制进程使用的RAM量,否则它不会对进程的虚拟内存大小产生任何影响。Windows 已经非常擅长动态控制这一点,当另一个进程需要 RAM 时按需交换内存页面。通过手动执行此操作,您的程序会减慢很多,当 Windows 被迫将内存页换回时会导致大量页面错误。 SetProcessWorkingSetSize 通常用于增加为进程分配的 RAM 量。或者在应用程序知道它将闲置很长时间时强制进行修剪。当您最小化应用程序的主窗口时,旧的 Windows 版本也会自动完成。

No need to pinvoke this btw, you can use the Process.GetCurrentProcess.Min/MaxWorkingSet properties.

不需要 pinvoke 这个 btw,你可以使用 Process.GetCurrentProcess.Min/MaxWorkingSet 属性。

回答by Zack Yezek

The only good use case I've seen for this call is when you KNOW your process is going to hog a lot of the system's RAM and you want to reserve it for the duration. You use it to tell the OS "Yes, I'm going to eat a lot of the system RAM during my entire run and don't get in my way".

对于这个调用,我见过的唯一好的用例是当您知道您的进程将占用系统的大量 RAM 并且您想在此期间保留它时。您可以使用它来告诉操作系统“是的,我将在整个运行过程中消耗大量系统 RAM,不要妨碍我”。

In that situation, leaving the OS's default behavior in place is bad. The OS allocates a default # of MB of RAM to each process- basically its workspace. Its resource management heuristics aren't oracles, so if they detect some process eating way more than its share of system resources (like RAM), they'll try to claw back as much of the excess as possible. For YOUR process this means the OS will waste a lot of CPU (and therefore hurt your performance) by paging memory in and out of your address space when it doesn't need to.

在这种情况下,保留操作系统的默认行为是不好的。操作系统为每个进程分配默认的 # MB RAM - 基本上是它的工作区。它的资源管理启发式方法不是预言机,因此如果它们检测到某个进程消耗的系统资源(如 RAM)份额超过其份额,它们将尝试尽可能多地收回多余的部分。对于您的进程,这意味着操作系统将在不需要时将内存分页进出您的地址空间,从而浪费大量 CPU(从而损害您的性能)。

回答by Maxim Masiutin

We have found out that, for a GUI application written in Delphi for Win32/Win64 or written in a similar way that uses large and heavy libraries on top of the Win32 API (GDI, etc), it is worth calling SetProcessWorkingSetSize once.

我们发现,对于用 Delphi 为 Win32/Win64 编写的 GUI 应用程序或以类似方式编写的在 Win32 API(GDI 等)之上使用大型和重型库的 GUI 应用程序,值得调用一次 SetProcessWorkingSetSize。

We call it with (... -1, -1) parameters, within a fraction of second after the application has fully opened and showed the main window to the user. In this case, the SetProcessWorkingSetSize(... -1, -1) releases lots of startup code that seem to not be needed any more. The memory quickly restores to about 1/3 of what it would have been without the SetProcessWorkingSetSize(... -1, -1), and does not grow more since then (unless the application allocates more memory). So we have effectively saved 2/3 of the memory of mostly startup code (loading and parsing of configuration files, initializing GUI, etc) that would not be needed to continue running the application.

在应用程序完全打开并向用户显示主窗口后的几分之一秒内,我们使用 (... -1, -1) 参数调用它。在这种情况下, SetProcessWorkingSetSize(... -1, -1) 释放了许多似乎不再需要的启动代码。内存迅速恢复到没有 SetProcessWorkingSetSize(... -1, -1) 时的大约 1/3,并且从那时起不会增长更多(除非应用程序分配更多内存)。因此,我们有效地节省了大部分启动代码(加载和解析配置文件、初始化 GUI 等)的 2/3 内存,这些代码不需要继续运行应用程序。

If you have a GUI application, you may test on your own application the same way - just call SetProcessWorkingSetSize once and see how many memory have been released definitely.

如果你有一个 GUI 应用程序,你可以用同样的方式在你自己的应用程序上测试 - 只需调用一次 SetProcessWorkingSetSize 并查看已经明确释放了多少内存。

Even for a server (service) application that don't have GUI - I think that calling SetProcessWorkingSetSize once after the server has fully loaded and initialized might have been useful.

即使对于没有 GUI 的服务器(服务)应用程序 - 我认为在服务器完全加载和初始化后调用一次 SetProcessWorkingSetSize 可能很有用。