11

I am aware of ulimit and I know how to limit memory for a process that I explicitly start, or start using a script. But in this case I have a service that is managed and launched by systemd.

How can I limit its max memory and have it killed (or even better: prevent it from memory allocation (return NULL to malloc / realloc)) when it reaches the memory usage maximum?

Petr
  • 324
  • 2
  • 4
  • 10

3 Answers3

10

The manpage for systemd.exec has a list of LimitXXXX instructions and a handy table comparing them to the ulimit options, by way of the setrlimit() system call.

To limit the process's entire address space (ulimit -v) use LimitAS=. Otherwise to limit the just the stack (ulimit -s) use LimitSTACK= or data segment (ulimit -d) use LimitDATA=

According to the setrlimit() manpage, these limits will cause allocating additional memory to fail. STACK and AS will terminate the program with a sigsegv if the limit is reached and the stack needs to grow (and the program did not handle this).

DerfK
  • 19,493
  • 2
  • 38
  • 54
  • Note that `setrlimit()` doesn't seem to be effective to limit amount of memory used with modern Linux kernels. You really want to use `cgroups` instead that allow much more fine-grained limits (both soft and hard) but the `Limit*` settings are not good for this. In addition, `cgroup` related options contain the whole service as a whole so you can control services that fork and run multiple children. See `cgroup` related options instead: https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html – Mikko Rantalainen Mar 27 '23 at 11:32
7

Systemd supports limiting memory usage via the MemoryLimit option, as described at: https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html

The way system handles the situation when maximum memory allowed (per service) is exhausted depends on both the underlying cgroups implementation and the way systemd implements resource control; I'm guessing the process would be killed (via OOM killer).

ivuk
  • 336
  • 1
  • 4
  • 3
    Would it restart the service when memory limit is reached? – Aftab Naveed Jul 12 '18 at 08:30
  • 1
    @AftabNaveed It terminates the task once the memory limit is reached, then the normal rules apply for a service that exited unexpectedly. So if you have something like `Restart=always` in the `.service` file then yes, it will restart after the memory limit has been reached. – Malvineous Sep 11 '21 at 05:28
4

For limits analogous to ulimit:

man systemd.exec

...
LimitAS=(like ulimit -v)
...
LimitRSS=(like ulimit -m)
...
Dan Armstrong
  • 821
  • 4
  • 6