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 / 533739
Accepted
sourcejedi
sourcejedi
Asked: 2019-08-04 11:22:14 +0800 CST2019-08-04 11:22:14 +0800 CST 2019-08-04 11:22:14 +0800 CST

O Linux realiza "troca oportunista" ou é um mito?

  • 772

Suponha que um programa peça alguma memória, mas não haja memória livre suficiente. Existem várias maneiras diferentes de o Linux responder. Uma resposta é selecionar alguma outra memória usada, que não foi acessada recentemente, e mover essa memória inativa para swap.

No entanto, vejo muitos artigos e comentários que vão além disso. Eles dizem que mesmo quando há uma grande quantidade de memória livre, o Linux às vezes decide escrever memória inativa para trocar. Gravar para swap com antecedência significa que, quando eventualmente quisermos usar essa memória, não teremos que esperar por uma gravação no disco. Eles dizem que esta é uma estratégia deliberada para otimizar o desempenho.

Eles estão certos? Ou isso é um mito? Cite sua(s) fonte(s).

Por favor, entenda esta questão usando as seguintes definições:

  • troca
  • memória livre - a memória "livre" exibida pelo comando free . Este é o MemFreevalor de /proc/meminfo. /proc/meminfoé um arquivo de texto virtual fornecido pelo kernel. Consulte proc(5) ou documentos do RHEL .
  • mesmo quando há uma grande quantidade de memória livre - para fins de argumento, imagine que há mais de 10% de memória livre.

Referências

Aqui estão alguns termos de pesquisa: linux "troca oportunista" OU (trocar "quando o sistema não tem nada melhor para fazer" OU "quando não tem nada melhor para fazer" OU "quando o sistema está ocioso" OU "durante o tempo ocioso")

No segundo resultado mais alto do Google, um usuário do StackExchange pergunta "Por que usar swap quando há espaço livre mais do que suficiente na RAM?" e copia os resultados do freecomando mostrando cerca de 20% de memória livre. Em resposta a esta pergunta específica, vejo que esta resposta é altamente votada:

O Linux começa a trocar antes que a RAM seja preenchida. Isso é feito para melhorar o desempenho e a capacidade de resposta:

  • O desempenho é aumentado porque às vezes a RAM é melhor usada para cache de disco do que para armazenar memória de programa. Portanto, é melhor trocar um programa que está inativo por um tempo e, em vez disso, manter os arquivos usados ​​com frequência no cache.

  • A capacidade de resposta é melhorada pela troca de páginas quando o sistema está ocioso, em vez de quando a memória está cheia e algum programa está sendo executado e solicitando mais RAM para concluir uma tarefa.

A troca diminui a velocidade do sistema, é claro - mas a alternativa à troca não é não trocar, é ter mais RAM ou usar menos RAM.

O primeiro resultado no Google foi marcado como uma duplicata da pergunta acima :-). Nesse caso, o autor da pergunta copiou os detalhes mostrando 7 MemFreeGB de 16 GB. A pergunta tem uma resposta aceita e votada:

Trocar apenas quando não há memória livre é apenas o caso se você definir swappinesscomo 0. Caso contrário, durante o tempo ocioso, o kernel fará a troca de memória. Ao fazer isso, os dados não são removidos da memória, mas uma cópia é feita na partição swap.

Isso significa que, se ocorrer uma situação de esgotamento da memória, ela não precisará gravar no disco imediatamente. Neste caso, o kernel pode apenas sobrescrever as páginas de memória que já foram trocadas, para as quais ele sabe que possui uma cópia dos dados.

O swappinessparâmetro basicamente apenas controla o quanto ele faz isso.

A outra citação não afirma explicitamente que os dados trocados também são retidos na memória. Mas parece que você preferiria essa abordagem, se estiver trocando mesmo quando tiver 20% de memória livre, e o motivo pelo qual está fazendo isso é melhorar o desempenho.

Até onde eu sei, o Linux suporta manter uma cópia dos mesmos dados na memória principal e no espaço de troca.

Também notei a alegação comum de que "troca oportunista" acontece "durante o tempo ocioso". Entendo que isso deve ajudar a me tranquilizar de que esse recurso geralmente é bom para o desempenho. Não incluo isso na minha definição acima, porque acho que já tem detalhes suficientes para fazer uma boa pergunta clara. Eu não quero tornar isso mais complicado do que precisa ser.

Motivação original

atop mostra `swout` (troca) quando tenho gigabytes de memória livre. Por quê?

Existem alguns relatórios como este, de Linux escrevendo para trocar quando há muita memória livre. A "troca oportunista" pode explicar esses relatórios. Ao mesmo tempo, pelo menos uma causa alternativa foi sugerida. Como primeiro passo para analisar as possíveis causas: O Linux alguma vez executa "troca oportunista" conforme definido acima?

No exemplo que relatei, a pergunta já foi respondida. A causa não foi a troca oportunista.

linux memory
  • 2 2 respostas
  • 2722 Views

2 respostas

  • Voted
  1. Best Answer
    sourcejedi
    2019-08-04T11:28:17+08:002019-08-04T11:28:17+08:00

    O Linux não faz "troca oportunista" conforme definido nesta pergunta.


    As seguintes referências primárias não mencionam o conceito:

    1. Entendendo o Gerenciador de Memória Virtual do Linux . Um livro online de Mel Gorman. Escrito em 2003, pouco antes do lançamento do Linux 2.6.0.
    2. Documentation/admin-guide/sysctl/vm.rst . Esta é a documentação principal das configurações ajustáveis ​​do gerenciamento de memória virtual do Linux.

    Mais especificamente:

    10.6 Daemon de Pageout (kswapd)

    Historicamente kswapdusado para acordar a cada 10 segundos, mas agora só é acordado pelo alocador de página física quando o número pages_low de páginas livres em uma zona é atingido. [...] Sob extrema pressão de memória, os processos farão o trabalho de kswapdforma síncrona. [...] kswapdcontinua liberando páginas até que a marca d'água pages_high seja atingida.

    Com base no exposto, não esperamos nenhuma troca quando o número de páginas gratuitas for maior que a "marca d'água alta".

    Em segundo lugar, isso nos diz que o objetivo kswapdé criar mais páginas gratuitas.

    Quando kswapdgrava uma página de memória para trocar, ela imediatamente libera a página de memória. kswapd não mantém uma cópia da página trocada na memória .

    Linux 2.6 usa o " rmap " para liberar a página. No Linux 2.4, a história era mais complexa. Quando uma página era compartilhada por vários processos, o kswapd não conseguia liberá-la imediatamente. Isso é história antiga. Todas as postagens vinculadas são sobre Linux 2.6 ou superior.

    troca

    Este controle é usado para definir o quão agressivo o kernel irá trocar as páginas de memória. Valores mais altos aumentarão a agressividade, valores mais baixos diminuirão a quantidade de swap. Um valor de 0 instrui o kernel a não iniciar a troca até que a quantidade de páginas livres e com suporte de arquivo seja menor que a marca d'água alta em uma zona.

    Esta citação descreve um caso especial: se você configurar o swappinessvalor como 0. Nesse caso, também não devemos esperar nenhuma troca até que o número de páginas de cache tenha caído para a marca d'água alta. Em outras palavras, o kernel tentará descartar quase todo o cache de arquivos antes de iniciar a troca. (Isso pode causar lentidão enorme. Você precisa ter algum cache de arquivo! O cache de arquivo é usado para armazenar o código de todos os seus programas em execução :-)

    Quais são as marcas d'água?

    As citações acima levantam a questão: Qual é o tamanho das reservas de memória de "marca d'água" no meu sistema? Resposta: em um sistema "pequeno", as marcas d'água de zona padrão podem chegar a 3% da memória. Isso se deve ao cálculo da marca d'água "min". Em sistemas maiores as marcas d'água serão uma proporção menor, aproximando-se de 0,3% da memória.

    Portanto, se a pergunta for sobre um sistema com mais de 10% de memória livre, os detalhes exatos dessa lógica de marca d'água não são significativos.

    As marcas d'água para cada "zona" individual são mostradas em /proc/zoneinfo, conforme documentado em proc(5) . Um extrato do meu zoneinfo:

    Node 0, zone    DMA32
      pages free     304988
            min      7250
            low      9062
            high     10874
            spanned  1044480
            present  888973
            managed  872457
            protection: (0, 0, 4424, 4424, 4424)
    ...
    Node 0, zone   Normal
      pages free     11977
            min      9611
            low      12013
            high     14415
            spanned  1173504
            present  1173504
            managed  1134236
            protection: (0, 0, 0, 0, 0)
    

    As "marcas d'água" atuais são min, lowe high. Se um programa pedir memória suficiente para reduzir freeabaixo minde , o programa entrará em "recuperação direta". O programa é feito para esperar enquanto o kernel libera memória.

    Queremos evitar a recuperação direta, se possível. Então, se freecair abaixo da lowmarca d'água, o kernel acorda kswapd. kswapdlibera memória trocando e/ou descartando caches, até que freeesteja acima highnovamente.


    Qualificação adicional: kswapdtambém será executado para proteger a quantidade total de lowmem_reserve, para uso de kernel lowmem e DMA. O lowmem_reserve padrão é cerca de 1/256 dos primeiros 4GiB de RAM (zona DMA32), portanto, geralmente é em torno de 16MiB.

    Confirmações de código Linux

    mm: dimensiona as marcas d'água do kswapd em proporção à memória

    [...]

    watermark_scale_factor:

    Este fator controla a agressividade do kswapd. Ele define a quantidade de memória restante em um nó/sistema antes que o kswapd seja ativado e quanta memória precisa ser liberada antes que o kswapd volte a dormir.

    A unidade está em frações de 10.000. O valor padrão de 10 significa que as distâncias entre marcas d'água são 0,1% da memória disponível no nó/sistema. O valor máximo é 1000 ou 10% da memória.

    Uma alta taxa de encadeamentos entrando em recuperação direta (allocstall) ou kswapd entrando em suspensão prematuramente (kswapd_low_wmark_hit_quickly) pode indicar que o número de páginas livres que o kswapd mantém por motivos de latência é muito pequeno para as rajadas de alocação que ocorrem no sistema. Este botão pode então ser usado para ajustar a agressividade do kswapd de acordo.

    proc: meminfo: estima a memória disponível de forma mais conservadora

    O MemAvailableitem em /proc/meminfoé dar aos usuários uma dica de quanta memória pode ser alocada sem causar troca, portanto, exclui as marcas d'água baixas das zonas como indisponíveis para o espaço do usuário.

    No entanto, para uma alocação de espaço de usuário, kswapdele será recuperado até que as páginas livres atinjam uma combinação da marca d'água alta e a proteção de memória baixa do alocador de página que mantém uma certa quantidade de memória DMA e DMA32 do espaço do usuário também.

    Subtraia o valor total que sabemos estar indisponível para o espaço do usuário do número de páginas gratuitas ao calcular MemAvailable.

    código Linux

    Às vezes, afirma-se que mudar swappinesspara 0desativará efetivamente a "troca oportunista". Isso fornece uma via interessante de investigação. Se houver algo chamado "troca oportunista" e puder ser ajustado por troca, podemos persegui-lo encontrando todas as cadeias de chamadas que lêem vm_swappiness. Observe que podemos reduzir nosso espaço de pesquisa assumindo que CONFIG_MEMCGnão está definido (ou seja, "cgroups de memória" estão desabilitados). A cadeia de chamadas vai:

    • vm_swappiness
    • mem_cgroup_swappiness
    • get_scan_count
    • shrink_node_memcg
    • shrink_node

    shrink_node_memcgé comentado "Esta é uma página básica por nó mais livre. Usada tanto pelo kswapd quanto pela recuperação direta". Ou seja, esta função aumenta o número de páginas livres . Ele não está tentando duplicar páginas para trocar para que possam ser liberadas muito mais tarde. Mas mesmo se descontarmos isso:

    A cadeia acima é chamada a partir de três funções diferentes, mostradas abaixo. Como esperado, podemos dividir os sites de chamada em recuperação direta versus kswapd. Não faria sentido realizar "trocas oportunistas" em recuperação direta.

    1. /*
       * Este é o caminho de recuperação direto, para processos de alocação de página. Nós apenas
       * tente recuperar páginas de zonas que satisfaçam a alocação do chamador
       * solicitar.
       *
       * Se uma zona for considerada cheia de páginas fixadas, basta dar uma luz
       * digitalize e desista.
       */
      static void shrink_zones
      
    2. * kswapd reduz um nó de páginas que estão no nível mais alto ou abaixo dele
       * zona que está atualmente desbalanceada.
       *
       * Retorna verdadeiro se o kswapd escaneou pelo menos o número de páginas solicitado
       * recuperação ou se a falta de progresso foi devido a páginas em writeback.
       * Isso é usado para determinar se a prioridade de varredura precisa ser aumentada.
       */
      static bool kswapd_shrink_node
      
    3. * Para kswapd, balance_pgdat() irá recuperar páginas em um nó de zonas
       * que são elegíveis para uso pelo chamador até que pelo menos uma zona seja
       *equilibrado.
       *
       * Retorna o pedido em que o kswapd terminou de reivindicar.
       *
       * kswapd varre as zonas na direção highmem->normal->dma. Ele pula
       * zonas que têm free_pages > high_wmark_pages(zone), mas uma vez que uma zona é
       * encontrado para ter free_pages <= high_wmark_pages(zone), qualquer página nessa zona
       * ou inferior é elegível para recuperação até que pelo menos uma zona utilizável seja
       *equilibrado.
       */
      estático int balance_pgdat
      

    Assim, presumivelmente, a alegação é que o kswapd é ativado de alguma forma, mesmo quando todas as alocações de memória estão sendo satisfeitas imediatamente a partir da memória livre. Examinei os usos de wake_up_interruptible(&pgdat->kswapd_wait), e não estou vendo nenhum despertar como este.

    • 17
  2. Nikolai
    2019-08-07T23:56:09+08:002019-08-07T23:56:09+08:00

    Não, não existe troca oportunista no Linux. Passei algum tempo analisando o problema e todas as fontes (livros didáticos, e-mails nas listas de e-mail dos desenvolvedores do kernel, código-fonte do Linux e comentários de commit, e algumas trocas no Twitter com Mel Gorman) estão me dizendo a mesma coisa: o Linux apenas recupera memória em resposta a alguma forma de pressão de memória (com a exceção óbvia da hibernação).

    Todos os equívocos populares sobre o assunto provavelmente derivam do simples fato de que o Linux não pode esperar até o último byte de memória livre antes de iniciar a troca. Ele precisa de algum tipo de almofada para protegê-lo de formas extremas de esgotamento de memória, e existem alguns ajustes que podem afetar o tamanho dessa almofada (por exemplo vm.min_free_kbytes, ). Mas não é o mesmo que "trocar porque não há nada melhor para fazer".

    Infelizmente, o algoritmo de recuperação de quadros de página tornou-se muito mais complexo em relação ao 2.6 (quando foi descrito em detalhes no livro de Mel Gorman), mas a ideia básica é mais ou menos a mesma: a recuperação de página é desencadeada por alocações com falha, que então acordar kswapdou tentar liberar páginas de forma síncrona (dependendo da pressão da memória, sinalizadores de alocação e outros fatores).

    A razão mais óbvia pela qual as alocações de página podem começar a falhar com memória livre suficiente restante é que elas podem estar solicitando memória contígua enquanto, na realidade, a memória pode estar muito fragmentada para satisfazer a solicitação. Historicamente, os desenvolvedores do kernel do Linux fizeram um grande esforço para evitar a necessidade de alocações contíguas. No entanto, alguns drivers de dispositivo ainda exigem isso - ou porque eles não podem fazer E/S de memória de várias páginas (DMA de dispersão de coleta), ou pode ser apenas uma codificação desleixada pelos desenvolvedores de drivers. O advento das Transparent Huge Pages (THP) forneceu outro motivo para alocar memória em blocos fisicamente contíguos.

    A compactação de zona, que foi introduzida no mesmo período, deve ajudar com o problema de fragmentação de memória, mas nem sempre produz o efeito esperado.

    Existem vários vmscanpontos de rastreamento que podem ajudar a entender exatamente o que está acontecendo em seu caso específico - é sempre mais fácil encontrar o que você precisa no código do kernel do Linux ao ter pilhas de chamadas específicas, em vez de apenas verificar tudo que parece remotamente relevante.

    • 6

relate perguntas

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

  • Necessidade de algumas chamadas de sistema

  • Um processo pode alocar memória cache de forma que o kernel possa aproveitá-la quando necessário?

  • 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