Como faço para parar rapidamente um processo que esteja causando a remoção (devido à alocação de memória excessiva)?

17

Nós todos experimentamos isso - alguns programas são solicitados a fazer algo que requer uma grande quantidade de memória. Ele diligentemente tenta alocar toda essa memória, e o sistema imediatamente começa a se debater, trocando interminavelmente e tornando-se lento ou não responsivo.

Mais recentemente experimentei isso no meu laptop Ubuntu devido a um script do Matlab tentando alocar uma matriz ridiculamente grande. Após ~ 5 + minutos de thrashing, eu consegui Ctrl-F1 para um console e matar o Matlab. Eu preferiria ter alguma tecla de atalho que me desse o controle do sistema imediatamente e me permitisse matar o processo ofensivo; ou, talvez, simplesmente silenciosamente se recuse a alocar um buffer tão grande.

  1. Qual é a maneira mais rápida de recuperar o controle de um sistema Linux que se tornou irresponsivo ou extremamente lento devido à troca excessiva?

  2. Existe uma maneira eficaz de evitar que essa troca ocorra, por exemplo, limitando a quantidade de memória que um processo pode tentar alocar?

por nibot 22.02.2011 / 02:02

6 respostas

11

Pressione Alt-SysRq-F para matar o processo usando a maior quantidade de memória:

  • A chave do SysRq geralmente é mapeada para a tecla Imprimir.
  • Se você estiver usando uma área de trabalho gráfica, talvez seja necessário pressionar Ctrl-Alt-SysRq-F caso pressionar Alt-SysRq acionar outra ação (por exemplo, programa de captura instantânea ).
  • Se você estiver usando um laptop, pode ser necessário pressionar uma tecla de função também.
  • Para mais informações, leia o artigo da wikipedia .
por 30.03.2011 / 15:57
4

Eu criei um script para essa finalidade - link

Eu tive este script em execução em servidores de produção, estações de trabalho e laptops com bom sucesso. Este script não mata os processos, mas os suspende temporariamente - Eu tive várias situações mais tarde, onde eu tenho certeza que tinha perdido o controle devido a thrashing, se não fosse por este script simples. No caso "pior", o processo ofensivo será muito lento e, no final, será eliminado pelo kernel (OOM), no caso "melhor" que o processo problemático realmente concluir ... em qualquer caso, o servidor ou a estação de trabalho permanecerá relativamente responsivo para que seja fácil investigar a situação.

Claro, "comprar mais memória" ou "não usar swap" são duas respostas alternativas mais tradicionais sobre a questão "como evitar a surra?", mas em geral elas tendem a não funcionar tão bem (instalando mais memória pode ser não-trivial, um processo desonesto pode consumir toda a memória, não importa o quanto tenha sido instalado, e pode-se entrar em problemas mesmo sem swap, quando não houver memória suficiente para buffering / caching). Eu recomendo o thrash-protect e muito espaço de troca.

    
por 08.08.2013 / 13:00
2

Você pode ser capaz de pressionar Ctrl - z para suspender o programa. Então você pode fazer kill %1 (ou qualquer que seja o número do trabalho ou você pode usar o PID).

Você pode usar o comando ulimit para tentar limitar a quantidade de memória disponível para um processo.

    
por 22.02.2011 / 02:07
2
  1. What is the quickest way to regain control of a Linux system that has become nonresponsive or extremely sluggish due to excessive swapping?

Já foi respondido acima com Alt-SysRq-F

  1. Is there an effective way to prevent such swapping from occurring in the first place, for instance by limiting the amount of memory a process is allowed to try to allocate?

Estou respondendo esta segunda parte. Sim, ulimit ainda funciona bem o suficiente para limitar um único processo. Você pode:

  • defina um limite flexível para um processo que você sabe que provavelmente ficará fora de controle
  • defina um limite rígido para todos os processos, se você quiser um seguro extra

Além disso, como mencionado brevemente:

You can use CGroups to limit resource usage and prevent such problems

De fato, os cgroups oferecem controle mais avançado, mas atualmente são mais complicados de configurar na minha opinião.

Ulimit da velha escola

Uma vez fora

Aqui está um exemplo simples:

$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)

  • Define um limite flexível de 1 GB de uso geral de memória (ulimit pressupõe limite na unidade kB)
  • Executa uma chamada de função bash recursiva r2(){ r2 $@$@;};r2 r2 que extinguirá exponencialmente a CPU e a RAM, duplicando-se infinitamente enquanto solicita a memória da pilha.

Como você pode ver, parou quando tentou solicitar mais de 1GB.

Observe que -v opera na alocação de memória virtual (total, ou seja, físico + swap).

Proteção permanente

Para limitar a alocação de memória virtual, as é o equivalente a -v para limits.conf .

Eu faço o seguinte para proteger contra qualquer processo de mau comportamento:

  • Defina um limite de espaço de endereçamento rígido para todos os processos.
  • address space limit = <physical memory> - 256MB .
  • Portanto, nenhum processo isolado com uso de memória voraz ou um loop ativo e vazamento de memória podem consumir TODA a memória física.
  • O espaço de
  • de 256 MB está disponível para processamento essencial com ssh ou console.

Um forro:

$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"

Para validar, isso resulta no seguinte (por exemplo, no sistema de 16 GB):

$ cat /etc/security/limits.d/mem.conf
*   hard    as      16135196
$ ulimit -H -v
161351960

Notas:

  • Apenas atenua um único processo que vai ao mar com o uso da memória.
  • Não impede uma carga de trabalho de vários processos com muita pressão na memória, causando a debulha (o cgroups é a resposta).
  • Não use a opção rss no limits.conf. Não é respeitado pelos novos kernels.
  • É conservador.
    • Em teoria, um processo pode solicitar especulativamente muita memória, mas somente usar ativamente um subconjunto (menor uso de conjunto de memória / residente de trabalho).
    • O limite máximo acima fará com que tais processos sejam abortados (mesmo que possam ter sido executados corretamente, caso o Linux permita que o espaço de endereço da memória virtual seja supercomprometido).

CGroups mais recentes

Oferece mais controle, mas atualmente é mais complexo de usar:

  • Aprimora a oferta ulimit.
    • memory.max_usage_in_bytes pode contabilizar e limitar a memória física separadamente.
    • Considerando que ulimit -m e / ou rss in limits.conf foi criado para oferecer funcionalidade semelhante, mas isso não funciona desde o kernel Linux 2.4.30!
  • É necessário ativar alguns sinalizadores de cgroup do kernel no carregador de inicialização: cgroup_enable=memory swapaccount=1 .
    • Isso não aconteceu por padrão com o Ubuntu 16.04.
    • Provavelmente devido a algumas implicações de desempenho da sobrecarga extra de contabilidade.
  • O material do cgroup / systemd é relativamente novo e está mudando um pouco, então o fluxo do fluxo de dados implica que os distribuidores de Linux ainda não o tornaram fácil de usar. Entre 14.04LTS e 16.04LTS, as ferramentas de espaço do usuário para usar cgroups foram alteradas.
    • cgm agora parece ser a ferramenta de espaço do usuário oficialmente suportada.
    • Os arquivos da unidade
    • systemd ainda não parecem ter nenhum padrão "vendor / distro" pré-definido para priorizar serviços importantes como o ssh.

Por exemplo para verificar as configurações atuais:

$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...

Por exemplo para limitar a memória de um único processo:

$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed

Para vê-lo em ação, chewing RAM como um processo em segundo plano e, em seguida, ser morto:

$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
 0.0  0.0  2876
 102  0.2 44056
 103  0.5 85024
 103  1.0 166944
 ...
98.9  5.6 920552
99.1  4.3 718196
[1]+  Killed                  bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'

Observe o crescimento exponencial (potência de 2) nas solicitações de memória.

No futuro, vamos esperar ver "distro / vendors" pré-configurar prioridades e limites do cgroup (via unidades systemd) para coisas importantes como SSH e a pilha gráfica, de tal forma que elas nunca fiquem famintas de memória.

    
por 07.11.2016 / 19:03
1

Você pode usar o CGroups para limitar o uso de recursos e evitar tais problemas: link

    
por 08.06.2015 / 07:06
0

It would be nice if the GUI had a hot key to send SIGSTOP to whatever application has focus!

Existe sempre o comando clássico xkill (do xorg-x11-apps-7.4-14.fc14.src.rpm no meu sistema). Eu acho que não deve ser muito difícil fazer um clone que envia SIGSTOP em vez de matar a janela de destino.

    
por 24.02.2011 / 01:32