AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 727101
Accepted
c--
c--
Asked: 2022-12-03 08:12:18 +0800 CST2022-12-03 08:12:18 +0800 CST 2022-12-03 08:12:18 +0800 CST

Por que os processos no Linux travam se usam muita memória, mas ainda menos do que a quantidade de espaço de troca disponível?

  • 772

Estou usando Linux 5.15 com Ubuntu 22.04.

Eu tenho um processo que usa muita memória. Requer mais memória do que tenho RAM na minha máquina. A primeira vez que o executei, foi morto pelo OOM Killer. Eu entendo isso: o sistema ficou sem memória, o OOM Killer foi acionado, meu processo foi encerrado. Isso faz sentido. Também tenho certeza de que foi isso que aconteceu: dei uma olhada dmesge está tudo lá.

Então eu adicionei algum espaço de troca. Não me importo se esse processo demorar muito para ser executado: não o executarei com frequência.

Executei o processo novamente. Desta vez, funcionou por mais tempo do que da primeira vez. Todo o sistema ficou muito lento, daquele jeito que os sistemas ficam quando estão trocando muito. Parecia estar funcionando... e então morreu. Não apenas o processo morreu, mas o processo shell que era seu pai também morreu, e o processo Tmux que era seu pai, e o processo shell que era pai do processo Tmux, e até mesmo o processo do terminal GNOME que era seu pai ! Mas então o processo de assassinato parou: nenhum outro pai morreu.

A princípio, pensei que o OOM Killer havia sido acionado novamente - embora ainda houvesse muito espaço de troca disponível - e que ele havia escolhido encerrar o processo do terminal GNOME. Mas eu verifiquei dmesge journalctl -knão havia nada de novo lá. Não havia sinal de que o OOM Killer havia sido acionado.

Então, primeira pergunta: existe alguma circunstância em que o OOM Killer pode ser acionado sem registrar nada no buffer de anel do kernel?

Fiquei intrigado com o fato de que o kernel do Linux parecia ter começado a trocar, mas de alguma forma não havia trocado o suficiente... ou não havia trocado rápido o suficiente... ou algo assim.

Então eu aumentei vm.swappiness. Isso realmente não deve afetar a estabilidade do sistema: é apenas um botão para girar para otimizar o desempenho. Mesmo com o kernel vm.swappinessdefinido 0, ainda deve iniciar a troca quando a memória livre em uma zona cair abaixo de um limite crítico.

Mas parecia que tinha começado a trocar, mas não havia trocado o suficiente ... então aumentei vm.swappinesspara 100incentivá-lo a trocar um pouco mais.

Então eu executei o processo novamente. Todo o sistema ficou muito lento, daquela forma que os sistemas fazem quando estão trocando muito ... até que o processo seja executado com sucesso até a conclusão.

Então, segunda pergunta: por que o kernel não usou o espaço de troca disponível, mesmo quando a memória livre caiu abaixo do limite crítico e certamente havia muito espaço de troca disponível? Por que a mudança vm.swappinessfez a diferença?

Atualizar:

Testes adicionais revelaram que a configuração vm.swappinessnão é uma solução confiável. Eu tive algumas falhas mesmo com vm.swappinessset to 100. Isso pode melhorar as chances de o processo ser concluído com sucesso, mas não tenho certeza.

linux
  • 3 3 respostas
  • 203 Views

3 respostas

  • Voted
  1. MC68020
    2022-12-10T04:47:12+08:002022-12-10T04:47:12+08:00

    Existem vários motivos para eventos OOM ocorrerem antes que o espaço de troca disponível seja totalmente usado e os eventos OOM podem acionar o thread OOM-killer ou pior… sinais desagradáveis:

    A/ Generalidades sobre alocação de memória e eventos OOM
    Porque os desenvolvedores do kernel estão cientes de que muitos programas malloc() enormes quantidades de memória “ just-in-case ” e não usam muito dela e, no mínimo, podem estaticamente esperar que todos os processos em execução no sistema não precisem simultaneamente da memória solicitada, o kernel na verdade não reserva a memória no ponto malloc (ou amigos).
    Em vez disso, ele aguardará o primeiro acesso de gravação na memória (o que levará necessariamente a uma falha de página) para fazer o mapeamento real.
    Se, neste ponto, não houver memória imediatamente disponível, o kernel aguardará por dias melhores (1) e, se esses dias melhores não vierem rápido o suficiente, disparará um evento OOM. Evento OOM que, dependendo de alguma configuração do sysctl (panic_on_oom) , acionará o OOM-killer ou gerará um kernel panic.

    B/ Por que os eventos OOM podem ocorrer independentemente da quantidade de espaço livre na troca (2)

    • B.1/ Porque o processo de troca não é rápido o suficiente para liberar espaço :
      Como visto em §A, o kernel não esperará muito para que alguma memória fique disponível. Portanto, se nenhum processo em execução liberar alguma memória e o cache do sistema de arquivos já estiver reduzido ao seu mínimo estrito, fazer com que a troca seja a única maneira de liberar páginas de memória ... isso simplesmente não caberá no período de tolerância. O evento OOM será disparado mesmo que Gigs de memória possam ter sido trocados.
      Os acessos aleatórios ao disco são lentos, o acesso à área de troca é ainda mais lento, pois o espaço de troca provavelmente está no mesmo disco que os sistemas de arquivos usados ​​pelos processos em execução.
      Existe, no entanto, uma maneira de tentar evitar que o sistema caia nessa situação. Lembre-se de Aquiles e a tartaruga: comece a trocar antes. Comece a mover as páginas no momento em que o sistema não precisar de memória física.
      Isso é o que você indiretamente (3) conseguiu obter ao aumentar o swappiness . Mas, como isso é apenas um efeito colateral de sua configuração, a configuração "melhor" sofre de um alto stdev e é altamente dependente da carga de trabalho. Benchmarks necessários. (4)(5)
    • B.2: Porque o sistema já trocou tudo que poderia ser trocado
      Processos usando a chamada de sistema mlock() podem obter páginas que são garantidas por design não trocáveis. Pior ? mlockall()(6)
      O que pode de fato resultar em uma boa quantidade de MB não substituíveis.
      As páginas HugeTLB também não podem ser trocadas sob pressão de memória, cat /proc/meminforelatarão a quantidade de memória reservada para atender a sua finalidade.

    C/ Por que os threads podem terminar quando a pressão da memória é alta sem que o OOM-killer registre nada . (7)

    • C.1: Por design de aplicativo
      A decisão de superalocar é tomada pelo kernel no momento mallocda emissão. E apesar dos padrões do kernel em uma "estratégia otimista" , sempre pode acontecer que o kernel recuse o pedido de reserva, retornando um ponteiro NULL para o malloc()thread de chamada.
      Nesse caso, dependendo de como o processo de chamada lida com essa exceção, ele aguardará melhores momentos para renovar sua solicitação ou simplesmente abortará graciosamente ou até mesmo ... simplesmente ignorará e segfault, encerrando ou causando a morte prematura dos pais em cascata, isso por sua vez, liberando uma boa quantidade de memória sem precisar da intervenção do OOM-killer. (e mais uma vez independentemente do espaço restante na troca)
    • C.2/ Porque algum encadeamento capturou algum sinal desagradável Como o sistema também pode tolerar a superalocação de páginas enormes, se nenhuma página enorme existir no tempo de falha de página, a tarefa recebe um SIGBUS e geralmente morre de maneira infeliz .

    1: Hmmm melhores milissegundos, na verdade, pois ele verificará até seis vezes no máximo, com alguns nanossegundos de espera entre eles. Observe que esses números pertencem à minha memória de kernels agora antigos, eles podem ter mudado desde então.

    2 : Observe que, estritamente falando, o Linux não troca , pois a troca se refere à transferência de um espaço de endereço de processo inteiro para o disco. O Linux realmente implementa a paginação , pois, de fato, transfere páginas individuais. No entanto, documentos e discussões usando troca … que assim seja.

    3: "indiretamente" porque começar a trocar mais cedo é apenas um efeito colateral dessa configuração que se destina principalmente a informar suas preferências de cache do sistema de arquivos em relação às páginas do processo.
    Como o IO do sistema de arquivos é caro, o Linux usará o máximo de memória física possível para o cache.
    Quanto maior o valor do swappiness, mais agressivo o sistema estará trocando as páginas do processo assim que o processo for iniciado, aumentando incidentalmente a quantidade de páginas de cache rapidamente recuperáveis ​​sob pressão de memória.

    4: Este BTW também explica o contrapositivo da sua pergunta: por que o sistema está trocando enquanto tem muita RAM livre disponível?

    5 : Embora possamos ler as principais instituições (RHEL, ORACLE…) aconselhando a configuração do swappiness ao mínimo estrito… (e comprar mais RAM…) Morton (um desenvolvedor de kernel líder) recomenda fortemente um valor de 100. Com a disponibilidade de tecnologias
    como como zswap , possivelmente tornando o custo de swap mais barato que o sistema de arquivos IO, valores de swappiness maiores que 100 nem seriam absurdos.

    6:

      mlockall() locks all pages mapped into the address space of the
       calling process.  This includes the pages of the code, data, and
       stack segment, as well as shared libraries, user space kernel
       data, shared memory, and memory-mapped files.  All mapped pages
       are guaranteed to be resident in RAM when the call returns
       successfully; the pages are guaranteed to stay in RAM until later
       unlocked.
    

    7 : Lembre-se de que, mesmo se iniciado, o OOM-killer é bastante... preguiçoso, preferindo que as tarefas desagradáveis ​​terminem sozinhas. Portanto, se houver sinais pendentes para o culpado… o OOM-killer aguardará que sua ação seja tomada… apenas por precaução…

    • 4
  2. Best Answer
    c--
    2022-12-13T04:52:37+08:002022-12-13T04:52:37+08:00

    Em primeiro lugar, gostaria de agradecer ao MC68020 por reservar um tempo para analisar isso para mim. Acontece que a resposta deles não incluiu o que realmente estava acontecendo nessa situação - mas eles receberam a recompensa de qualquer maneira, pois é uma ótima resposta e uma referência útil para o futuro.

    Também gostaria de agradecer a Philip Couling por sua resposta, que também não estava certa, mas me apontou na direção certa.

    O problema acabou sendo systemd-oomd .

    O problema e sua solução são descritos aqui: Como desabilito o matador de processos OOM systemd no Ubuntu 22.04?

    Resumidamente:

    systemctl disable --now systemd-oomd
    systemctl mask systemd-oomd
    

    E agora posso executar meu processo de forma confiável até a conclusão todas as vezes, sem que algum serviço systemd elimine toda a árvore do processo sem aviso prévio.

    • 3
  3. Philip Couling
    2022-12-10T06:07:15+08:002022-12-10T06:07:15+08:00

    Não estou ciente de nenhuma causa que possa resultar nos processos de morte do assassino OOM, mas não registrei o fato. Há um caso extremo em que o OOM Killer pode desativar o processo responsável por gravar os logs do kernel no disco. Isso parece improvável pela sua descrição.

    Eu tomaria dois detalhes de sua descrição como importantes e relacionados:

    • A falta de um log OOM-Killer
    • O fato de que toda a árvore do processo, incluindo a janela da GUI , desapareceu.

    É um palpite, mas parece que a própria GUI está matando.

    É bem possível que a surra estivesse fazendo parecer que estava quebrado. Já vi exemplos em que, por exemplo, os navegadores travaram devido a uma intensa surra. Os detectores de falhas não podem ver nenhuma atividade e assumem que o próprio programa deu errado, sem entender que o programa estava simplesmente esperando a resposta do Kernel.

    Eu tentaria trocar de console e executá-lo a partir de uma linha de comando sem a GUI. Isso pelo menos descartaria qualquer interferência do próprio GNOME.

    • 1

relate perguntas

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve