Remi.b
Remi.b

Reputation: 18229

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

I am reading this answer by @AlexGray that explains how to limit memory usage of a process on MAC OSX.

The answer says:

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.

I fail to understand this answer. I am not really aware of what a launchd item is (although I now read a bit about it), barely know what a plist and a key are and the link to the Apple-s MAN page appears broken.

Can you please help me by making a simple fully reproducible example on how to use this solution?

Upvotes: 2

Views: 4684

Answers (1)

Rob Napier
Rob Napier

Reputation: 299455

(This probably isn't a great answer; it may get you on the right road, but it may not be enough information and it may not even be possible. But it's more info than you have now.)

Memory usage is a complex topic. It is very difficult to define in a precise way how much memory a process is using because it's not at all clear which parts to count. For example, the executable itself is generally memory mapped to disk and shared between processes using the same executable, with various parts paged into RAM at any given time. Should this count as 0 bytes, the entire size of the image, the size of the pages currently mapped, the size of the pages currently unswappable, etc? As you enter the world of virtual (and now compressed) memory, "how much memory is this process using?" gets even murkier.

At WWDC a few years ago I asked Apple how I could put absolutely hard limits on my own process's resource usage. (I wanted this because as a daemon process I wanted to make sure I didn't take over the system, even if it meant my service died.) They indicated that it wasn't really possible. I don't know if that's changed.

But launchd might help (maybe it'll at least log something). The tool would be a LaunchAgent. These are not easy or well documented. The best docs there are is the Daemons and Service Programming Guide.

You'll want a configuration file along these lines:

<?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>

See man launchd.plist for details. Maybe SoftResourceLimits would work instead.

This file goes into ~/Library/LaunchAgents. launchctl has radically changed recently. You used to have to call launchctl load, but it may autostart now. See launchctl kickstart as another way to get it running.


(right… ulimit doesn't work on modern versions of OS X, so all the below is useless.) But putting all that to the side, the tool you want here is ulimit, not launchd. (launchd is very complicated, poorly documented, and Apple completely redid its whole interface recently so lots of older docs don't apply anymore).

ulimit is part of bash. You can use it to constrain subprocesses for various resources. The easiest way to see them all is 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

You probably want to modify "data seg size" or "virtual memory." For example, to limit the process to 1MB, you might use ulimit -d 1024 before launching the program.

Upvotes: 5

Related Questions