c++ - 防止控制台应用程序中的内存工作集最小化?

标签 c++ visual-studio memory

我想在控制台应用程序中防止内存工作集最小化。 在 Windows 应用程序中,我可以通过 overriding SC_MINIMIZE messages 来完成. 但是,如何在控制台应用程序中拦截 SC_MINIMIZE? 或者,我可以通过其他方式阻止内存工作集最小化吗?

我使用 Visual Studio 2005 C++。 有人遇到了一些问题,解决方案并不令人满意。 :( http://www.eggheadcafe.com/software/aspnet/30953826/working-set-and-console-a.aspx

提前致谢。

最佳答案

工作集修剪只能通过锁定内存中的页面来防止,或者通过使用 VirtualLock 显式锁定它们或者通过将内存映射到 AWE .但是这两个操作都具有极高的特权,并且需要应用程序在被授予“内存中的锁定页面”的帐户下运行 特权,请参阅 How to: Enable the Lock Pages in Memory Option .默认情况下,没有人,不是 vene 管理员,有这个特权。

从技术上讲,这就是您正在寻找的答案(忽略了如何识别要锁定的区域的“次要”细节)。但是你的问题表明你走的路完全错误。

Wroking set trimming 是经常发生的事情,没有严重的不利影响。您很可能将修整与调出内存混淆,但它们是内存页面生命周期的不同阶段。当操作系统从进程中移除页面映射并将页面放入备用列表时,就会发生修整。这是一个非常快速和简单的操作:页面被添加到备用列表中,pte被相应地标记。没有IO操作发生,物理RAM内容没有改变。如果进程再次访问修剪后的页面,就会发生软故障。 TLB 未命中将触发进入内核空间,内核将在备用列表中找到该页面并将其重新分配给进程。快速,快速,简单,再一次,没有 IO 操作发生,页面的 RAM 内容也没有发生任何变化。因此,如果一个进程的所有工作集都被修剪,那么如果它继续引用页面,它将很快(微秒)重新获得整个事件集。

只有当操作系统需要新页面用于其空闲列表时,它才会查看备用列表,获取最旧的页面并将其实际交换到磁盘。在这种情况下确实发生了 IO,并且 RAM 内容被清零。当进程再次访问该页面时,将发生硬故障。 TLB 未命中将唤醒内核,这将检查 pte 的列表,现在将发生“真正的”页面错误:分配一个新的空闲页面,从磁盘读取内容,然后将页面分配给进程,然后执行从 TLB 未命中位置恢复。

如您所见,工作集修剪和内存压力页面交换之间存在巨大差异。如果您的控制台应用程序被修剪,请不要担心。通过在内存中锁定页面,您将对系统健康造成无法估量的更大损害。顺便说一句,您还因为误解了页面生命周期而在被要求最小化时拒绝最小化,从而造成类似的糟糕用户体验。

的确,有些进程有合理的要求来保持其工作集尽可能热。所有这些过程总是作为服务实现的。服务受益于操作系统更宽松的修整策略,并且该策略实际上是可配置的。

如果您真的关心系统内存并想帮助操作系统,您应该使用 CreateMemoryResourceNotification 注册内存通知。并通过释放缓存来应对内存压力,并在您收到可用内存可用通知时增加缓存。

关于c++ - 防止控制台应用程序中的内存工作集最小化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2115185/

相关文章:

c# - 由于内存泄漏,Xamarin Forms 应用程序重新架构)

c++ - 如何删除密码屏蔽c++中的字符

c++ - 二维指针数组的类型定义

c++ - 关于 C/C++ 标准中的时间/空间复杂度

c++ - 返回简历 :Mat pointer to main function

C# - Visual Studio - 发布先决条件错误

.net - 用于简化命令行参数编辑的 Visual Studio 插件

c# - 运行 DELETE SQL 查询后 ASP.NET 页面不刷新

memory - 确定可用的视频内存

c++ - 实例化 C++ 类时内存中会发生什么