Alguma descrição sobre como ulimit
funciona:
ulimit
lidou com setrlimit
e getrlimit
chamadas do sistema. É fácil garantir por strace
-ing do processo bash ( ulimit
é componente do bash
). Eu defino 1024kb de max memory size
:
$ ulimit -m 1024
Em outro console:
$ strace -p <my_bash_pid>
. . .
getrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
setrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
. . .
setrlimit
man page escreve em seguida sobre RLIMIT_RSS
:
RLIMIT_RSS Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.
madvice
syscall é apenas um conselho para o kernel e o kernel pode ignorar este conselho. Mesmo bash
man page sobre ulimit
, escreva:
-m The maximum resident set size (many systems do not honor this limit)
Essa é a razão pela qual -m
não funciona.
Sobre a opção -v
:
Eu defino 1024 kb de memória virtual:
$ ulimit -v 1024
Em outro console:
$ strace -p <my_bash_pid>
. . .
getrlimit(RLIMIT_AS, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
setrlimit(RLIMIT_AS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
. . .
setrlimit
man page escreve em seguida sobre RLIMIT_AS
:
RLIMIT_AS The maximum size of the process's virtual memory (address space) in bytes. This limit affects calls to brk(2), mmap(2) and mremap(2), which fail with the error ENOMEM upon exceeding this limit. Also automatic stack expansion will fail (and generate a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)). Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited.
O programa consiste em 3 segmentos (dados, código, pilha) que compõem o espaço de memória do programa virtual.
-
O segmento do código é const e contém instruções do programa.
-
O segmento de dados é controlado da seguinte forma:
brk
syscall ajusta o tamanho do segmento de dados (parte da memória virtual ) do programa.mmap
syscall mapeia o arquivo ou dispositivo para a memória virtual do processo.Muitos programas alocam memória (direta ou indireta) chamando a função padrão da Biblioteca C (
malloc
) que aloca memória de heap (parte do segmento de dados).malloc
ajusta o tamanho do segmento de dados chamandobrk
syscall. -
O Stack armazena variáveis de funções (a variável recebe memória durante a alocação da pilha).
Então, é por isso que a opção -v
funciona para você.
Se -v
for suficiente para sua tarefa, não há motivos para fazer outra coisa e é suficiente.
Se você deseja controlar grandes quantidades de recursos de memória específicos para processos (pressão de memória, uso de swap, limite de RSS, OOM e assim por diante), sugiro que você use pacotes de memória .
Se seu aplicativo for um serviço , sugiro que você use Recursos do systemd slice , como o mais conveniente para controlar e limitar recursos de serviço ou grupo de serviços (também é fácil configurar em vez de configurar cgroups
diretamente) que é gerenciado por systemd
.