Como domesticar a capacidade de resposta, memória e paginação do Linux


27

Primeira pergunta sobre estouro =) ... +100 em recompensa. Não conseguia pensar em algo que realmente me importava até agora:

Estou realmente farto do estado de resposta do desktop Linux, por exemplo, http://brainstorm.ubuntu.com/item/85/ - em situações com pouca RAM livre ou em situações com alto rendimento de disco, o sistema fica lento para um rastreamento ; isso é absolutamente terrível para aplicativos que exigem desempenho decente. Além disso, a interface do usuário não responde. Compare isso, por exemplo, com o OS X, onde, se um aplicativo estiver consumindo recursos, sempre é possível clicar com o botão direito para forçá-lo a sair, enquanto no Linux eu não posso nem usar a tecla alt ou alternar a área de trabalho, ou até mesmo ctrl-alt-f1 para obter um terminal - bem, posso, leva apenas 1-2 minutos por operação.

Eu uso o gkrellm para que eu possa ver a situação à medida que ela se desenrola. Normalmente, a utilização da memória se torna bastante alta ou a taxa de transferência do disco aumenta consideravelmente.

Não é um hardware ruim, com um quad-core de 2.6GHz e 4GB de RAM DDR2 de 800MHz (teria 6GB, mas devido a uma incompatibilidade de hardware não era possível combinar com o conjunto antigo). Esse problema pode desaparecer quando eu inevitavelmente adquirir mais memória RAM, mas não acho que esse seja o coração do problema. Eu tenho até duas partições de swap em discos diferentes.

Sinto que o problema é triplo:

  • programas descontrolados que consomem grandes quantidades de memória - a lei deve ser estabelecida para esses programas, com limites
    • (por exemplo, guias no Chrome, cada uma com 20 a 50 MB, algumas das quais podem usar centenas de MB)
    • (por exemplo, outros programas, como update-db e indexadores, que tive que desativar e remover do cron porque eles estavam diminuindo a velocidade do rastreamento do sistema sempre que eram executados, etc.)
  • algo terrível acontecendo na contenção do kernel ou do barramento de algum tipo, de modo que situações de alta taxa de transferência de disco atrasam todo o sistema para um rastreamento (talvez paginando programas importantes)
  • o kernel não prioriza a interface do usuário ou programas importantes em termos de recursos, como memória, paginação e até utilização do processador

Os upvotes vão para:

Estou, portanto, procurando uma solução em que todos esses programas desapareçam. Em particular, estou procurando uma solução para que os processos desacelerem proporcionalmente, enquanto o sistema e outros programas permanecem totalmente inalterados e responsivos o tempo suficiente para matar algo manualmente. Além disso, o processo do gerenciador de janelas (e qualquer outra coisa que possa afetar a capacidade de resposta da interface do usuário) deve ser responsivo em todas as circunstâncias.

Em particular, estou intrigado com /etc/security/limits.conf( man limits.conf), mas estou preocupado que isso só dê controle por usuário, e os exemplos comentados no arquivo parecem bastante opacos em termos de descrição ou por onde começar. Espero que limits.conffuncione, mas não ficaria surpreso se nem sequer funcionasse, ou se não fosse uma solução apropriada para o meu problema, ou tão granular quanto estou tentando alcançar. Um nome por processo limits.confseria ideal, assumindo novamente que o limits.conf funciona. Eu ficaria feliz em experimentar os limites.conf que as pessoas fornecem, para testar se funciona, embora eu esteja aberto a todas as soluções neste momento.

Também pode ser útil ter idéias sobre como o OS X consegue manter uma boa capacidade de resposta da interface do usuário.

Já ajustei minhas /tmppastas cache e cache e tmpfs, em geral, a utilização do disco é quase zero.

Tópicos vagamente relacionados:

  • supercomprometimento de memória

Respostas que acho que não funcionarão:

  • swapoff (isso ainda permite que os programas de consumo de memória se safem de assassinatos e o sistema congela permanentemente se a memória é realmente ruim - é favorável a qualquer pessoa que possa sugerir um ajuste que invocou o assassino de OOM mais cedo antes de trocar e direcionar programas específicos)
  • echo ?? > /sys/.../swappiness (nenhum efeito discernível)
  • nice (nunca funcionou)
  • ionice (nunca notei uma diferença)
  • selinux (incompatibilidade de programa parece ser um pesadelo)
  • linux em tempo real, ou seja, pode interromper o kernel (não deseja lidar com a compilação e atualização do kernel personalizado; pode ser bom se ele tiver migrado para os repositórios)
  • *

hmm, pareço incapaz de fazer uma recompensa; ? Eu acho que o link não aparecer para 48hr ... bem, eu estarei postando a recompensa com toda a reputação que adquiri depois
user76871

1
+1, esse é o maior problema que eu tenho com a área de trabalho do Linux diariamente. Tenho congelamentos ocasionais, talvez uma vez a cada duas semanas, mas esses não costumam ser o bastante para ficar particularmente irritantes. No entanto, apenas parece haver um problema com aplicativos que possuem, como você disse, alta utilização de E / S : aplicativos com alta utilização de CPU têm pouco ou nenhum efeito no desempenho geral do sistema. Não conhecia a ionice, parece que seria a solução correta para esse problema se funcionasse corretamente.
Crazy2be 16/05

1
3 anos depois e isso ainda é um problema no Linux. @ crazy2be ou user76871, acho que você não encontrou uma solução nesse meio tempo?
Glutanimado

@ Glutanimate: sim, 32 GB de RAM física e nada menos (bem, talvez 16 GB ... mas isso está aumentando), também pode haver grandes quantidades de RAM de vídeo. Isso não corrige a falta de resposta devido à alta CPU ou interrupções ou outros enfeites, mas evita a falta de resposta em situações de pouca memória.
user76871

Respostas:


6

Parece que seu sistema entra em trocas pesadas. O uso vmstat 1pode revelar alguns detalhes - deixe-o rodar em uma janela do terminal e mude para ele quando a desaceleração começar.

Em vez de colocar / tmp e "cache" em tmpfs, eu usaria um sistema de arquivos em disco normal montado com a noatimeopção Os dados frequentemente usados ​​permanecem nos caches de qualquer maneira, e os dados mais antigos podem ser gravados no disco para liberar RAM para aplicativos. Se / tmp e / ou cache aumentarem, isso pode ajudar bastante.


1
+1 por mencionar noatime.
LawrenceC

Obrigado por mencionar noatime, infelizmente eu costumava usar essa opção de montagem e não acho que tenha ajudado muito a garantir capacidade de resposta (embora ajude muito a garantir que o disco não esteja sobrecarregado); só para ter certeza de que reativei o noatime na minha configuração atual. Ter um não-tmpfs com noatime parece um pouco estranho, já que eu ainda imagino que gravações em massa devam acontecer.
User76871

+1, tentou vmstat 1- extremamente útil no diagnóstico conquistar essa troca é, na verdade, uma grande parte do problema principal questão
user76871

2
Ai. Nunca vi um sistema Linux que precisava de uma troca tão pesada. Você verificou df -mquanta memória é usada nos sistemas de arquivos tmpfs? Algo está consumindo sua RAM relativamente rápido.
Turbo J

obrigado pela sugestão e me ensinando sobre a -mopção. Infelizmente, df -h -mparece indicar que existem apenas 100 MB de memória tmpfs, então duvido que esteja relacionado ao uso de memória para tmpfs e caches. Isso também não parece tão incomum; Eu tive isso acontecer em várias distribuições quando a RAM é empurrada para perto do limite.
User76871

5

Não sou desenvolvedor de kernel, mas passei anos filosofando sobre esse assunto, porque me deparei com isso muitas vezes. Na verdade, eu criei uma metáfora para toda a situação, então deixe-me dizer uma coisa. Vou assumir na minha história que coisas como "swap" não existem. De qualquer forma, a troca não faz muito sentido com 32 GB de RAM atualmente.

Imagine um bairro em que a água esteja conectada a cada prédio por meio de canos e as cidades precisem gerenciar a capacidade. Vamos supor que você tenha apenas uma produção de 100 unidades de água por segundo (e toda a capacidade não utilizada será desperdiçada porque você não possui tanques de reservatório). Cada residência (residência = um pequeno aplicativo, um terminal, o widget de relógio etc.) requer uma unidade de água por segundo. Tudo isso é bom e bom porque sua população tem cerca de 90 anos e todo mundo recebe água suficiente.

Agora, o prefeito (= você) decide que deseja abrir um restaurante grande (= navegador). Este restaurante abrigará vários cozinheiros (= guias do navegador). Cada cozinheiro precisa de 1 unidade de água por segundo. Você começa com 10 cozinheiros, portanto o consumo total de água para todo o bairro é de 100 unidades de água, o que ainda é bom.

Agora começa a coisa divertida: você contrata outro cozinheiro em seu restaurante, o que faz com que as necessidades totais de água sejam 101 que obviamente você não tem. Você precisa fazer alguma coisa.

O gerenciamento de água (= kernel) tem 3 opções.

1. A primeira opção é simplesmente desconectar o serviço para as casas que não usaram a água recentemente. Isso é bom, mas se a casa desconectada quiser usar a água novamente, precisará passar pelo longo processo de registro novamente. A gerência pode desconectar várias casas para liberar mais recursos hídricos. Na verdade, eles desconectam todas as casas que não usaram água recentemente, mantendo sempre uma certa quantidade de água livre sempre disponível.

Embora sua cidade continue funcionando, a desvantagem é que o progresso é interrompido. A maior parte do seu tempo é gasta na espera pelo gerenciamento da água para restabelecer seu serviço.

Isto é o que o kernel faz com as páginas suportadas por arquivo. Se você executar um executável grande (como o chrome), seu arquivo será copiado na memória. Quando estiver com pouca memória ou se houver partes que não foram acessadas recentemente, o kernel poderá descartá-las porque pode recarregá-las do disco de qualquer maneira. Se isso for feito excessivamente, isso interromperá a área de trabalho, pois tudo estará aguardando a E / S do disco. Observe que o kernel também eliminará muitas das páginas usadas menos recentemente quando você começar a fazer muitas IO. É por isso que leva séculos para mudar para um aplicativo em segundo plano depois que você copia vários arquivos grandes, como imagens de DVD.

Esse é o comportamento mais irritante para mim, porque eu odeio vadias e você não tem controle sobre isso. Seria bom poder desligá-lo. Estou pensando em algo ao longo das linhas de

sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c

e então você pode definir vm_swappiness como -1 para desativar isso. Isso funcionou muito bem nos meus pequenos testes, mas infelizmente não sou desenvolvedor de kernel, então não enviei para ninguém (e, obviamente, a pequena modificação acima não está completa).

2)A gerência poderia negar o pedido de água do novo cozinheiro. Isso inicialmente parece uma boa ideia. No entanto, existem duas desvantagens. Primeiro, existem empresas que solicitam muitas assinaturas de água, mesmo que não as usem. Uma razão possível para fazer isso é evitar toda a sobrecarga de conversar com o gerenciamento de água sempre que eles precisarem de um pouco de água. O uso da água sobe e desce dependendo da hora do dia. Por exemplo, no caso do restaurante, a empresa precisa de muito mais água ao meio-dia em comparação à meia-noite. Portanto, eles solicitam toda a água possível que possam usar, mas isso desperdiça alocações de água durante a meia-noite. O problema é que nem todas as empresas podem prever seu pico de uso corretamente, de modo que solicitam muito mais, na esperança de que nunca precisem se preocupar em solicitar mais.

É isso que a máquina virtual do Java faz: aloca um monte de memória na inicialização e depois trabalha com isso. Por padrão, o kernel alocará a memória apenas quando seu aplicativo Java realmente começar a usá-lo. No entanto, se você desativar a confirmação excessiva, o kernel levará a reserva a sério. Só permitirá que a alocação seja bem-sucedida se ela realmente tiver os recursos para isso.

No entanto, há outro problema mais sério com essa abordagem. Digamos que uma empresa comece a solicitar uma única unidade de água todos os dias (e não nas etapas de 10). Eventualmente, você chegará a um estado em que possui 0 unidades gratuitas. Agora, esta empresa não poderá alocar mais. Tudo bem, quem se importa com as grandes empresas de qualquer maneira. Mas o problema é que as pequenas casas também não poderão solicitar mais água! Você não poderá construir pequenos banheiros públicos para lidar com o repentino fluxo de turistas. Você não poderá fornecer água de emergência para o incêndio na floresta próxima.

Em termos de computador: em situações de pouca memória sem confirmação excessiva, você não poderá abrir um novo xterm, não poderá conectar-se à sua máquina, não poderá abrir uma nova guia para procurar possíveis Conserta. Em outras palavras, desativar o overcommit também torna a área de trabalho inútil quando a memória está baixa.

3. Agora, aqui está uma maneira interessante de lidar com o problema quando uma empresa começa a usar muita água. A gestão da água explode! Literalmente: vai ao local do restaurante, joga dinamites nele e espera até que exploda. Isso reduzirá instantaneamente as necessidades de água da cidade para que novas pessoas possam se mudar, você pode criar banheiros públicos etc. Você, como prefeito, pode reconstruir o restaurante na esperança de que desta vez exija menos água. Por exemplo, você dirá às pessoas para não irem aos restaurantes se já houver muitas pessoas dentro (por exemplo, você abrirá menos guias do navegador).

Na verdade, é isso que o kernel faz quando fica sem todas as opções e precisa de memória: ele chama o OOM killer. Ele pega um aplicativo grande (baseado em muitas heurísticas) e o mata, liberando muita memória, mas mantendo uma área de trabalho responsiva. Na verdade, o kernel do Android faz isso de forma ainda mais agressiva: mata o aplicativo menos usado recentemente quando a memória está baixa (em comparação com o kernel padrão que faz isso apenas como último recurso). Isso é chamado de Viking Killer no Android.

Eu acho que essa é uma das soluções mais simples para o problema: não é como se você tivesse mais opções do que isso; por que não superar isso mais cedo ou mais tarde, certo? O problema é que o kernel às vezes faz bastante trabalho para evitar a chamada do killer do OOM. É por isso que você vê que sua área de trabalho é muito lenta e o kernel não está fazendo nada a respeito. Mas, felizmente, existe uma opção para invocar o assassino da OOM! Primeiro, verifique se a tecla sysrq mágica está ativada (por exemplo echo 1 | sudo tee /proc/sys/kernel/sysrq) e, sempre que sentir que o kernel está com pouca memória, basta pressionar Alt + SysRQ, Alt + f.

OK, então tudo isso é legal, mas você quer experimentar? A situação de pouca memória é muito simples de reproduzir. Eu tenho um aplicativo muito simples para isso. Você precisará executá-lo duas vezes. A primeira execução determinará a quantidade de RAM livre disponível; a segunda execução criará a situação de pouca memória. Observe que este método pressupõe que você tenha desabilitado o swap (por exemplo, faça a sudo swapoff -a). Código e uso a seguir:

// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int limit = 123456789;
    if (argc >= 2) {
        limit = atoi(argv[1]);
    }
    setbuf(stdout, NULL);
    for (int i = 1; i <= limit; i++) {
        memset(malloc(1 << 20), 1, 1 << 20);
        printf("\rAllocated %5d MiB.", i);
    }
    sleep(10000);
    return 0;
}

E aqui está como você o usa:

$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed

A primeira chamada detectou que temos 31.118 MiB de RAM livre. Então eu disse ao aplicativo para alocar 31.110 MiB de RAM para que o kernel não o mate, mas consome quase toda a minha memória. Meu sistema congelou: até o ponteiro do mouse não se mexeu. Pressionei Alt + SysRQ, Alt + f e isso acabou com meu processo eatmem e o sistema foi restaurado.

Embora tenhamos coberto nossas opções, o que fazer em uma situação de pouca memória, a melhor abordagem (como qualquer outra situação perigosa) é evitá-la em primeiro lugar. Há muitas maneiras de fazer isso. Uma maneira comum que eu vi é colocar os aplicativos que se comportam mal (como navegadores) em contêineres diferentes do resto do sistema. Nesse caso, o navegador não poderá afetar sua área de trabalho. Mas a prevenção em si está fora do escopo da pergunta, então não vou escrever sobre isso.

TL; DR: embora atualmente não haja como evitar totalmente a paginação, você pode atenuar a interrupção total do sistema desativando a confirmação excessiva. Mas seu sistema continuará inutilizável durante situações de pouca memória, mas de uma maneira diferente. Independentemente do exposto, em uma situação de pouca memória, pressione Alt + SysRQ, Alt + f para interromper um grande processo de escolha do kernel. Seu sistema deve restaurar sua capacidade de resposta após alguns segundos. Isso pressupõe que você tenha a chave sysrq mágica ativada (não é por padrão).


Dei a você toda a minha reputação de recompensa por esse recurso, então não pude deixar um comentário :) Finalmente, ganhei alguns para agradecer por esta ótima resposta! Eu estava lidando com esse problema o tempo todo em meu laptop com 8 GB (louco, mas meu sistema ficava sem memória regularmente naqueles dias). Recentemente, encontrei este projeto: github.com/rfjakob/earlyoom , que pode ajudar a impedir que o sistema seja interrompido , matando alguns processos antes que seja tarde demais.
21817 Vlad Frolov

4

Colocar todos os seus arquivos temporários e de cache em um tmpfsestá diminuindo a quantidade de RAM livre que você possui, portanto, você pode fazer com que o sistema troque mais cedo do que seria necessário sem isso.

Parece que você tem alguns aplicativos que contam com algum tipo de instalação ou driver do kernel que está sendo sobrecarregado. Você não entra em muitos detalhes sobre que tipos de aplicativos, além de navegadores e indexadores, e que desativou os indexadores.

Você pode tentar mudar para um ambiente de área de trabalho ou gerenciador de janelas que consome menos recursos, como LXDE ou IceWM. No trabalho, uso um sistema Linux com o LXDE instalado e o ROX-Filer para um ambiente de desktop muito mínimo. O objetivo deste sistema Linux é executar o VMWare Player para que eu possa executar o Windows XP e o Windows 7 simultaneamente. São especificações de hardware semelhantes às que você diz e não tenho muitos problemas de capacidade de resposta sob essa carga pesada em que estou submetendo o hardware. Não tenho nenhum problema de responsividade com o próprio Linux (geralmente são as VMs que às vezes me fazem esperar um segundo, e o compartilhamento de 1 disco entre 2 VMs + 1 SO é esperado) e sempre foram capazes de suspender ou desligar as VMs sempre que necessário. Eu quero.

Então, para mim, isso indica algum problema com aplicativos específicos que você está executando.

O DMA está ativado para suas unidades de disco? (use hdparm) Se você estiver usando criptografia de disco completo, isso exige que todo o tráfego de disco passe pela CPU, o que nega grande parte dos benefícios do DMA. O efeito disso seria que o alto tráfego de disco causa um pico na CPU, o que atrasaria todo o sistema. (EDIT: para esclarecer, ter o DMA desativado OU usar dm-cryptcausará alta CPU durante alto tráfego de disco)


2
O ponto principal da questão não é que o WM esteja inchado e causando lentidão no sistema (provavelmente é perfeitamente responsivo sob uso normal), mas que o kernel não prioriza corretamente os aplicativos quando fica sem memória e precisa entrar em troca pesada. Eu já tive esse problema em todos os desktops Linux que já usei e, embora o uso de programas mais leves ou a adição de mais memória ram possam ajudar, ele não aborda a raiz do problema.
22411 crazy2be

No post anterior, eu disse o seguinte: "Parece que você tem alguns aplicativos que dependem de algum tipo de instalação ou driver do kernel que está sendo sobrecarregado". Então, talvez o gargalo esteja em um módulo específico do kernel. Não sou especialista em kernel, mas tenho certeza de que a alocação de memória do lado do kernel, especialmente do lado do módulo, está funcionando de maneira diferente da do lado do usuário. A utilização da CPU no lado do kernel também é provavelmente tratada de maneira diferente (não sei se você pode "agradar" os processos do kernel). Não posso comentar mais sem conhecer os aplicativos específicos envolvidos.
LawrenceC

Além disso, se você estiver usando o FUSE NTFS, isso pode causar lentidão.
LawrenceC

1
Estou ciente de que um sistema de arquivos baseado em RAM, como tmpfs (obviamente), faz com que a RAM se esgote mais rapidamente e que um WM leve pode reduzir levemente os sintomas do problema subjacente. Senti-me pressionado a usar tmpfs devido à baixa capacidade de resposta que a gravação no disco pode causar. No entanto, obrigado por sua sugestão, especialmente a parte sobre DMA, que adicionei à lista de tópicos possivelmente relacionados. Para o registro, acredito que o DMA está ativado e não estou usando um sistema de arquivos criptográficos.
User76871

1

Este é um problema comum com o agendador do Linux. O sistema diminui para um rastreamento sempre que atividades pesadas de E / S ocorrem. Não há realmente muitas coisas que você poderia fazer para melhorar a situação, a menos que você goste de hackear o kernel :)

Talvez estes possam ajudar:

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video&num=1

http://www.osnews.com/story/24223/Alternative_to_the_200_Lines_Kernel_Patch_that_Does_Wonders_


1
Pelo que me lembro, esses patches do kernel são realmente relevantes apenas se você estiver compilando um programa ou fazendo outra coisa que é muito CPU (e IO?) Pesada em um terminal , enquanto tenta interagir com aplicativos GUI. Isso não ajuda na situação mais comum em que um aplicativo GUI está realizando algum trabalho pesado e você está tentando trabalhar com outro aplicativo GUI, infelizmente.
22811 crazy2be

0

Embora a pergunta tenha mais de dois anos e a resposta da @ ypsu seja ótima, a situação dos sistemas baseados em Linux está ruim devido à falta de RAM ainda está aqui.

Aqui está minha observação sobre o problema: mesmo que eu não tenha nenhuma troca, uma vez que o sistema está com pouca memória, o indicador do meu disco rígido acende, pois é 100% da carga do disco. Dado esse fato, parece que a causa principal é que o kernel tenta liberar memória descarregando algo que pode ser restaurado do disco e, certamente, as bibliotecas compartilhadas. Como os aplicativos GUI geralmente têm toneladas de bibliotecas compartilhadas, parece que o sistema pode pensar que é suficiente apenas descarregar algumas delas, mas isso só funciona até a próxima operação de espaço do usuário que requer essas bibliotecas descarregadas de volta. Esse parece ser o cenário mais provável, causando o loop sem fim de descarregar bibliotecas compartilhadas e carregá-las novamente.

Há um projeto que atua como um daemon de espaço do usuário, matando os processos que consomem mais memória antes que seja tarde demais: https://github.com/rfjakob/earlyoom

Além disso, eu costumava usar contêineres do Docker com limites de memória sã para aplicativos com muita memória (por exemplo, Chrome).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.