I want to limit the memory usage of a child process using rlimit. Currently our code is as follows:
old_rlimit := get_rlimit()
set_rlimit(child_process_rlimit)
cmd.Start()
set_rlimit(old_rlimit)
cmd.Wait()
However, sometimes Golang runtime will report out of memory error at cmd.Start()
. It seems that in cmd.Start()
current process will allocate some memory, and if current memory usage is higher than child_process_rlimit
, an error will be raised.
I want to know is there any way to limit the memory usage of child process without affecting current one?
You need to apply rlimit
to the child process only rather than relying on rlimit inheritance. Your main blocker here is clearly spelled out in the setrlimit
man page:
an unprivileged process may set only its soft limit to a value in the range from 0 up to the hard limit, and (irreversibly) lower its hard limit
The standard way to do this is through fork/exec, something along the lines of:
child_pid := fork()
if pid != 0 {
// in child process
setrlimit(...)
execve(...)
}
If you don't want to do that, you still have a few options:
cmd.Run
a small wrapper (eg: bash ulimit -m ...
) that calls the child process. note: -m
is not honored by many systems.prlimit
(linux-specific and no syscall wrapper. see this thread for details)