We have a process that in recent weeks had a once-off memory leak that resulted in it consuming all memory on our RHEL 7 box
We now wish to set limits around this such that it will never take any more than a certain amount
We are using the ulimit -v setting to set this amount (as the -m setting does not work)
Therefore, I'm wondering if this is sufficient or do we also need a way to limit physical memory as well? IF so, what is the best way to go about this?
If virtual memory always grows with phyiscal memory then perhaps -v by itself is sufficient
Best Answer
Some description about how
ulimit
works:ulimit
has deal withsetrlimit
andgetrlimit
system calls. It's easy to ensure bystrace
-ing of bash process (ulimit
is component of thebash
). I set 1024kb ofmax memory size
:In another console:
setrlimit
man page write next aboutRLIMIT_RSS
:madvice
syscall is just advice to kernel and kernel may ignore this advice. Evenbash
man page aboutulimit
write following:That is the reason why
-m
doesn't work.About
-v
option:I set 1024 kb of virtual memory:
In another console:
setrlimit
man page write next aboutRLIMIT_AS
:Program consist of 3 segments (data, code, stack) compose virtual program memory space.
Code segment is const and contain program instructions.
Data segment is controlled by following:
brk
syscall adjusts size of data segment (part of virtual memory) of the program.mmap
syscall maps file or device to virtual memory of process.Many programs allocates memory (direct or indirect) by calling standard function from C Library (
malloc
) which allocates memory from heap (part of data segment).malloc
adjust size of data segment by callingbrk
syscall.Stack stores functions variables (variable takes memory during allocation from stack).
So, that's why the
-v
option is works for you.If
-v
is sufficient for your task, then there is no reasons to do something else and it's sufficient.If you want to take control about huge count of specific memory features for process (memory pressure, swap usage, RSS limit, OOM and so on) I suggest to you to use cgroups memory capabilities.
If your application is a service I suggest to you to use systemd slice features, as the most convenient for controlling and limiting resources of service or group of services (also it easy to configure instead of configuring
cgroups
directly) which is managed bysystemd
.