2

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?

Remi.b
  • 17,389
  • 28
  • 87
  • 168
  • What do you hope to make happen if your program tries to use more memory than it's allowed? And why? – Ken Thomases Mar 04 '18 at 21:10
  • @KenThomases I want to send it a kill signal. My goal is to benchmark several softwares for performing a set of different simulations. Any time a software overpass a set resource (whether memory or CPU time), I want and just report that the software was too slow or used too much RAM to benchmark it. Ultimately, I am looking for something like `{ /usr/bin/time -l limitation ${MaxTime} ${MaxMemory} myProcess arg1 arg2; } 2> data.txt`, where `limitation` is some command that would limits the resources used by a process and kill this process if it overpass those resources. – Remi.b Mar 04 '18 at 21:15
  • @KenThomases I'm happy to edit my post to set out exactly my goal if you think it is worth it. I was just cared to ask for too a broad problem and be suggested many of the related posts that failed to help me so far (I've been on this problem for quite a few days now). Let me know if you think I should edit the post. Thanks a lot for your help – Remi.b Mar 04 '18 at 21:23
  • Did you come up with anything useful regarding this? – fakedrake Nov 22 '19 at 20:23

1 Answers1

6

(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.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 1
    I am afraid ulimit just does not work on recent MAC OS as explained in the post I linked ([this post](https://stackoverflow.com/questions/3274385/how-to-limit-memory-of-a-os-x-program-ulimit-v-neither-m-are-working)). I can confirm it is not working for me. I vaguely understand that memory is a complex question. I am fine with many reasonable measures such as the "resident set size" typically (assuming this term is well defined). – Remi.b Mar 05 '18 at 02:42