Eu acho que não é um problema tão incomum: um processo aloca grandes quantidades de memória (seja devido a um erro de vazamento de memória, porque você tenta processar um arquivo de entrada inviávelmente grande ou o que for). A RAM enche e, em algum momento, o Linux precisa mudar para trocar. Bem, às vezes esse é apenas o último recurso: se eu tiver uma computação cara, não quero perder dados se, no final, ficar sem memória RAM.
Mais frequentemente, porém (na minha experiência), o consumo de memória é ilimitado, por um processo desonesto, talvez com erros. Ou seja, eu não acabo apenas com alguns dados menos urgentemente necessários movidos para troca, mas o sistema operacional é forçado a trocar panicamente cargas de dados. Infelizmente, isso não apenas interrompe fortemente o processo ofensivo, mas pode paralisar todo o sistema (não é mais tão ruim em máquinas com SSD, mas o OTOH) me preocupa se escrever gigabytes e gigabytes de dados de lixo pode a longo prazo prejudicar as células flash).
Até eu perceber o problema e interromper manualmente o processo (uma vez que demorou alguns minutos até eu me conectar a um terminal virtual!), Metade da minha sessão de corrida está em troca, e preciso esperar um pouco até o sistema funcionar sem problemas novamente.
Há uma solução dracônica para o problema: impor um limite de memória rígida. Mas fazer isso em todo o sistema às vezes mata processos que eu ainda preciso, e se eu precisar manualmente ulimit
antes de iniciar um processo ofensivo ... bem, muitas vezes esquecerei até que seja tarde demais.
Possíveis tipos de solução que eu ficaria mais feliz com:
- Se algum processo exceder um determinado uso de memória, ele será artificialmente acelerado para que o restante do sistema permaneça responsivo.
- Se algum processo exceder um determinado uso de memória, é necessário
SIGSTOP
que eu tenha tempo para descobrir o que fazer a seguir. - Se um processo se aproximar do limite de RAM, recebo um aviso antes do início da grande troca.
Existe alguma maneira de obter esse comportamento, ou similar?
ulimit
é para.Respostas:
niceload --noswap yourprg é feito exatamente para essa situação: Ele analisa a atividade de troca:
Ele não suspende o processo antes do início da troca, mas permite que a troca seja executada por 1 segundo antes de agir.
niceload --mem 1G yourprg
funciona da mesma forma: se menos de 1 GB estiver livre, o youprg será suspenso. Quando mais de 1 GB estiverem disponíveis, o seu programa será reiniciado.fonte
Sim. É muito fácil de fazer com praticamente qualquer shell moderno.
Você pode usar a
-l
opção para limites de memória bloqueados. Seu processo será sinalizado se o limite for excedido.fonte
Cronjob para limpar o cache: Como limpar o cache de memória no Linux
Na verdade, tenho problemas semelhantes. Eu tenho vários usuários que executam seus próprios scripts personalizados e de vez em quando seus scripts consomem toda a memória disponível e derrubam o servidor redhat. O motivo do consumo em massa de RAM foi que seus scripts podem ser executados por dias apenas aguardando um evento, consumindo recursos quando, na realidade, ele não está usando nenhum. Então, o que eu fiz foi simplesmente forçar a limpeza do cache com um cronjob e não tive nenhum problema desde então.
Simples e preguiçoso.
fonte