Eu desprezo fortemente qualquer tipo de assassino automático de OOM e gostaria de resolver essas situações manualmente. Então, há muito tempo eu tenho
vm.overcommit_memory=1
vm.overcommit_ratio=200
Mas desta forma, quando a memória transborda, o sistema deixa de responder. No meu antigo laptop com HDD e 6 GB de RAM, às vezes eu tinha que esperar muitos minutos para mudar para um VT de texto, emitir alguns comandos e esperar que eles fossem executados. É por isso que tenho vários indicadores de desempenho para perceber tais situações com antecedência e frequentemente recebo perguntas sobre por que eu precisaria deles. E nem sempre ajudam também, porque se ocorreu um estouro de memória quando eu não estava no laptop, já é tarde demais.
Suspeitei que a situação seria melhor em um laptop mais novo com SSD e 12 GB de RAM, mas na verdade é ainda pior. Eu tenho zRam com vm.swappiness=200
, que permite até 16,4 GB de swap compactado, e quando está quase extinto, o sistema fica ainda mais sem resposta do que no laptop antigo, a ponto de até mesmo o switch VT mal funcionar, e também não consigo fazer SSH no sistema da rede local, então meu único recurso é invocar cegamente o OOM manual do kernel com Alt+SysRq+RF, que às vezes opta por matar processos importantes como dbus-daemon
. Eu poderia criar um daemon com um alerta sonoro quando a troca estiver quase cheia, mas isso é um paliativo parcial novamente, já que posso não chegar a tempo de qualquer maneira.
No passado, tentei mitigar tais situações com thrash-protect
. Ele envia SIGSTOP
para processos gananciosos e SIGCONT
os envia automaticamente, o que ajudou muito a adiar o bloqueio total e resolver a situação manualmente, mas em condições de forte sobrecarga, ele começa a congelar praticamente tudo (o que pode ser explicitamente incluído na lista de permissões). E tem muitos efeitos colaterais irritantes. Por exemplo, se um shell estiver congelado, seus processos filhos poderão permanecer congelados após o descongelamento do shell. Se dois processos compartilham um barramento de mensagens e um deles está congelado, as mensagens são rapidamente acumuladas no barramento, o que leva ao rápido crescimento do uso de RAM novamente ou a travamentos (servidores gráficos e navegadores multiprocessos são especialmente propensos a isso).
Tentei rodar sshd
com prioridade -20, como sugerido na pergunta semelhante , mas isso realmente não ajuda: não responde tanto quanto com a prioridade padrão.
Eu gostaria de ter algum console de emergência que esteja sempre bloqueado na RAM e possa ser usado independentemente de quão sobrecarregado esteja o resto do sistema. Algo semelhante à tela Ctrl+Alt+Del no Windows NT≥6, ou ainda melhor. Dado que é possível reservar um pouco de RAM com o crashkernel
parâmetro que uso para kdump
, suspeito que também seja possível explorar este ou algum outro mecanismo do kernel para a tarefa.
Para o seu caso de uso, tente a
mlockall
chamada do sistema para forçar um processo específico a nunca ser trocado, evitando assim a lentidão da troca.Eu recomendaria
earlyoom
regras personalizadas sobre esse hack.Você precisa de uma partição swap ou de um arquivo swap contíguo.
Utiliza-se espaço de troca para controlar o que acontece quando os programas alocam toda a memória real e desejam mais. Após todo o cache liberável (alguns blocos em cache estão "em uso" e não podem ser liberados) ter sido liberado, o sistema entra no estado Out-Of-Memory. Na condição Out-Of-Memory, com swap, alguma memória da tarefa é gravada no disco (trocada), liberada para reutilização e posteriormente devolvida à memória (trocada) quando a tarefa é executada. Sem swap, o sistema pode congelar, o temido OOM-Killer (um pseudoprocesso, codificado no kernel) é executado e escolhe um processo para KILL, a fim de liberar memória. O OOM-Killer é conhecido por escolhas inconvenientes.
A hibernação do sistema requer uma área de troca contígua do tamanho de RAM.
Leia
man mkswap fallocate filefrag swapon fstab
.