如何在 MAC OSX 上限制程序内存使用的示例

Example of how to limit memory usage of a program on MAC OSX

我正在阅读@AlexGray 的 this answer,它解释了如何限制进程在 MAC OSX 上的内存使用。

答案是:

You can setup a launchd item for your executable.. The important part of the plist is a section, such as..

    <key>SoftResourceLimits</key> <dict>
       <key>Stack</key>
       <integer>10000000000</integer> 
    </dict> 

There are various keys available... which can be found on Apple's MAN page.

我没看懂这个答案。我真的不知道什么是 launchd 项目(尽管我现在读了一点),几乎不知道什么是 plist 和一个密钥,Apple-s MAN 页面的 link 似乎坏了。

你能帮我做一个简单的完全可复制的例子来说明如何使用这个解决方案吗?

(这可能不是一个很好的答案;它可能会让你走上正确的道路,但它可能没有足够的信息,甚至可能是不可能的。但它比你现在拥有的信息更多。)

内存使用是一个复杂的话题。很难以精确的方式定义一个进程使用了​​多少内存,因为根本不清楚要计算哪些部分。例如,可执行文件本身通常是内存映射到磁盘,并在使用相同可执行文件的进程之间共享,并且在任何给定时间都会将各个部分分页到 RAM 中。这应该算作 0 字节、图像的整个大小、当前映射的页面大小、当前不可交换的页面大小等吗?当您进入虚拟(现在压缩)内存的世界时,"how much memory is this process using?" 变得更加模糊。

几年前在 WWDC 上,我问 Apple 我如何才能对我自己的进程的资源使用设置绝对严格的限制。 (我想要这个是因为作为一个守护进程,我想确保我没有接管系统,即使这意味着我的服务已经终止。)他们表示这实际上是不可能的。不知道改了没有。

但是 launchd 可能会有所帮助(也许它至少会记录一些东西)。该工具将是一个 LaunchAgent。这些都不容易或有据可查。最好的文档是 Daemons and Service Programming Guide.

您需要一个配置文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.myproject</string>
    <key>ProgramArguments</key>
    <array>
        <string>path-to-executable</string>
        <string>any-parameter-if-needed</string>
    </array>
    <key>HardResourceLimits</key>
    <dict>
       <key>ResidentSetSize</key>
       <integer>10000000000</integer> 
    </dict>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>

有关详细信息,请参阅 man launchd.plist。也许 SoftResourceLimits 会起作用。

此文件进入 ~/Library/LaunchAgents。 launchctl 最近发生了翻天覆地的变化。您以前必须调用 launchctl load,但它现在可能会自动启动。请参阅 launchctl kickstart 作为另一种获取方式 运行。


(对...... ulimit 不适用于 OS X 的现代版本,因此以下所有内容均无用。) 但是把所有这些放在一边,你在这里想要的工具是 ulimit,而不是 launchd。 (launchd 非常复杂,文档很少,Apple 最近完全重新设计了它的整个界面,因此许多旧文档不再适用)。

ulimit 是 bash 的一部分。您可以使用它来约束各种资源的子流程。查看全部的最简单方法是 ulimit -a:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 7168
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1418
virtual memory          (kbytes, -v) unlimited

您可能想要修改 "data seg size" 或 "virtual memory." 例如,要将进程限制为 1MB,您可以在启动程序之前使用 ulimit -d 1024