
Ao escrever um programa, há momentos em que um programa descontrolado consome metade da minha RAM (geralmente devido a loops praticamente infinitos durante a criação de grandes estruturas de dados) e torna o sistema tão lento que não consigo nem matar o programa agressor. Então, quero usar o ulimit para encerrar meu programa automaticamente quando ele estiver usando uma quantidade anormal de memória:
$ ulimit -a
core file size (blocks, -c) 1000
data seg size (kbytes, -d) 10000
scheduling priority (-e) 0
file size (blocks, -f) 1000
pending signals (-i) 6985
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) 10000
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 6985
virtual memory (kbytes, -v) 100000
file locks (-x) unlimited
$ ./run_program
mas por que meu programa ainda está usando mais RAM do que o limite determinado (sim, estou iniciando o programa no mesmo shell bash)?
Eu entendi mal alguma coisa sobre ulimit?
Responder1
Seu exemplo deve funcionar como você pensa (o programa é encerrado após consumir muita RAM). Acabei de fazer um pequeno teste no meu servidor shell:
Primeiro eu restringi meus limites para serem MUITO baixos:
ulimit -m 10
ulimit -v 10
Isso fez com que quase tudo fosse morto. ls
, date
e outros pequenos comandos serão disparados antes mesmo de começarem.
Qual distribuição Linux você usa? Seu programa usa apenas um único processo ou gera vários processos filhos? Neste último caso, o ulimit pode nem sempre ser eficaz.
Responder2
ulimit -m
não funciona mais. Use ulimit -v
em vez disso.
A razão é que ulimit
chama setrlimit ehomem definir limitediz:
RLIMIT_RSS Especifica o limite (em bytes) do conjunto residente do processo (o número de páginas virtuais residentes na RAM). Este limite tem efeito apenas no Linux 2.4.x, x < 30, e afeta apenas chamadas para madvise(2) especificando MADV_WILLNEED.
Responder3
Isso funciona apenas em uma única sessão bash, a menos que você o coloque em seu .bash_profile e não se aplique aos processos já em execução.
O que acho estranho é que:
max memory size (kbytes, -m) unlimited
não está presente em /etc/security/limits.conf mesmo que limite apenas o consumo de memória por processo e não geral para 1 conta de usuário. Em vez de adicionarem o Cgroup, eles deveriam apenas modificar os comandos Unix existentes para acomodar esses novos recursos.