设置Windows进程(或用户)的内存限制。

51

有没有办法在Windows XP中为进程设置系统范围内的内存限制?我有几个不稳定的应用程序,它们通常工作得很好,但可能会遇到错误,导致在几秒钟内消耗掉所有内存(至少我认为是这样)。这会导致Windows完全失去响应并强制重新启动,因此会丢失我的工作。

我希望能够像Linux上的/etc/limits那样做一些事情-例如设置M90(将单个用户的最大内存设置为90%),以便无论如何系统都可以获得剩余的10%。


BartPE可以做到这样的事情,所以应该是可能的。但我不知道具体怎么做。 - OregonGhost
2
@Michał Minicki,您能详细说明所选答案如何帮助您吗?据我所知,它描述了如何使用WINAPI解决问题,但没有提供通用的应用程序来挂起、钩取和包装现有进程到CreateJobObject中。我错过了什么? - Lorenz Lo Sauer
@OregonGhost,你有关于那个能力的更多信息吗? - Lorenz Lo Sauer
寻找有关Superuser.com的答案... - kokbira
5个回答

38

用户能否在标准的Windows安装中使用“作业对象”(例如控制Web浏览器的总资源利用率),或者操纵它们是开发人员/程序员专属功能(在没有诸如Process Governor之类的工具的情况下)?(代朋友询问…) - Jim Grisham

24

使用微软的Application Verifier (AppVerifier)工具。

在我的情况下,我需要模拟内存不再可用,因此我在工具中执行了以下操作:

  1. 添加我的应用程序
  2. 取消选择基本选项
  3. 选中低资源模拟
    • 将TimeOut更改为120000-我的应用程序将在2分钟内正常运行,然后任何事情都会生效。
    • 将HeapAlloc更改为100-堆分配错误的几率为100%
    • 设置Stacks为true-堆栈将无法增长
  4. 保存
  5. 启动我的应用程序

2分钟后,我的程序无法再分配新的内存,我能够看到如何处理一切。


4

根据您的应用程序,限制语言解释器使用的内存可能更容易。例如,对于Java,您可以设置JVM将分配的RAM数量。

否则,可以使用Windows API为每个进程设置一次。

SetProcessWorkingSetSize函数


10
这并不实际限制进程可以占用的内存总量,只是限制了任意特定时间分页的内存量。这可能大部分时间对于原帖作者有效,但正确限制进程可使用的总内存量的答案是使用作业对象(job object)。 - Stephen Martin

3
我不知道有任何方法可以做到这一点,但我非常好奇是否有人有一个好的答案。我一直在考虑将这样的功能添加到我们公司构建的应用程序之一中,但是没有找到一个好的方法来实现它。
我能想到的唯一一件事(虽然不是直接相关的)是,我相信您可以限制Windows中COM+应用程序的总内存使用量。当然,这需要编写运行在COM+中的应用程序,但这是我所知道的最接近的方式。
工作集的内容很好(作业对象也控制工作集),但那不是总内存使用量,而只是任何时候实际内存使用量(分页)。它可能适合您想要的内容,但据我所知,它不能限制总分配内存。

3
JobObjects 可以控制作业或进程可以提交的最大虚拟内存量。请查看 SetInformationJobObject 和 JOBOBJECT_EXTENDED_LIMIT_INFORMATION 结构。 - Stephen Martin

2

每个进程的限制

从最终用户的角度来看,在超级用户问题“在Windows上是否有可能限制特定进程的内存使用量”中,有一些有用的答案和评论,包括如何在任何或所有以下设置递归配额限制:

  • CPU分配 (数量、亲和力、NUMA组)
  • CPU使用率,
  • RAM使用量 (包括“已提交”和“工作集”),以及
  • 网络使用量。

大多数情况下,可以通过内置的Windows“作业对象”系统(如上面提到的@Adam Mitz的答案@Stephen Martin的评论)来实现,使用:

  • 注册表(如果需要持久性)或
  • 免费工具,例如开源的Process Governor

(注意:嵌套的作业对象可能并非在所有早期版本的Windows下都可用,但未嵌套的版本似乎可以追溯到Windows XP)

每用户限制

每用户的总配额而言:

  • ??
  • 可能每个用户会话自动分配给一个作业组本身;如果是这样,应该可以将每个用户的限制应用于该作业组 更新:不是这样的;作业对象只能在创建时或与特定进程关联时进行嵌套,并且在某些情况下,子作业对象被允许从其父级中“脱离”并变得独立,因此它们不能实现“每用户”的资源限制。
NTFS确实支持每个用户的文件系统配额,但是。
系统级别的限制:
除了简单的BIOS或“能源配置文件”限制外:
虚拟机超级管理程序或Kubernetes样式的容器资源限制控件可能是最直接的选项(至少从最终用户可理解性方面来看)。
脚注,关于针对非Windows系统的每个进程和其他资源配额/ QoS:
  • ‘经典’ Mac OS (包括在 2000 年代版本的 Mac OS X 上运行的‘经典’应用程序):可以在目标程序的 Finder‘获取信息’窗口的‘内存’部分中轻松设置每个应用程序的内存限制;作为使用协作多任务并发模型的系统,每个进程的 CPU 限制是不可能的。
  • BSD:?(可能与 Linux 和非专有 macOS 方法有一些重叠?)
  • macOS (又名‘Mac OS X’):没有用户界面;系统支持包括,根据版本不同,‘多处理服务 API’Grand Central Dispatch、POSIX 线程 / pthread、‘操作对象’和 可能 其他
  • Linux:‘资源管理器’/limits.conf控制组/‘cgroups’、进程优先级/‘niceness’/renice,其他吗?
  • IBM z/OS 和其他类似主机风格的系统:资源控制/分配从一开始就内置了

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接