Como aumentar o espaço máximo de troca no Mac OS X?

14

No Mac OS X Yosemite 10.10.5, quando tento executar um cálculo que precisa alocar e usar 128 GB de memória (é um programa de linha de comando escrito em C), o kernel mata meu processo com extremo preconceito. Esta entrada de log do console é um exemplo de uma instância:

25/09/15 7: 08: 40.000 PM kernel [0]: troca baixa: matando o pid 6202 (huffgrp)

O cálculo funciona bem e em um período de tempo razoável quando aloca e usa 64 GB de memória. Meu Mac possui 32 GB de RAM e espaço de beaucoup no disco rígido. Eu também tentei isso em outro Mac com 8 GB de RAM, no qual o cálculo de 64 GB também funciona bem, demorando mais, é claro, mas o cálculo de 128 GB é eliminado pelo kernel da mesma maneira.

A propósito, malloc()nunca retorna um erro, não importa quanto espaço eu peça. O kernel mata apenas o processo quando uma quantidade excessiva de memória estiver realmente sendo usada pelo processo, resultando em muitas trocas no disco rígido.

Portanto, parece haver um limite de espaço de troca secreto entre 64 GB e 128 GB.

Minha pergunta é: como reconfigurar o kernel para permitir mais espaço de troca? Encontrei um arquivo promissor /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist, mas não vejo o número secreto lá. A página de manual dynamic_pagerdiz que tudo o que faz é definir o nome e o local dos arquivos de troca. Há uma versão mais antiga da mesma página do manual que documenta uma -Sopção para definir o tamanho dos arquivos de troca criados. Eu tentei isso, solicitando swapfiles de 160 GB, mas não teve efeito. Os arquivos de troca ainda tinham 1 GB cada e o processo ainda foi morto pelo kernel.

Mark Adler
fonte
Também postei esta pergunta no apple.stackexchange.com, mas não houve resposta lá.
Mark Adler #
1
A razão pela qual você pode mallocmais do que tem é porque o commit_limit é muito alto (provavelmente infinito). Portanto, o sistema operacional alocará a memória que não possui (isso significa que o processo não o utilizará, o sistema operacional geralmente vence essa aposta). Você pode ajustar o limite de confirmação para ser o limite de memória, desta forma o processo falhará mais cedo.
ctrl-alt-delor 27/09/15
Não vejo por que você entende que o parágrafo 5 é verdadeiro, mas não segue o parágrafo 4 (embora você o inicie com "so"). Você também tentou adicionar muita troca? (a pergunta não está clara, embora eu suspeite que a resposta seja sim).
ctrl-alt-delor 27/09/15
@richard Sim, eu sei por malloc()que isso acontece. Eu estava desviando possíveis comentários sobre alguém pensando que não estou verificando o valor de retorno malloc(). A propósito, meu objetivo não é falhar antes. Meu objetivo é ter sucesso.
Mark Adler
@richard Porque a mensagem do kernel diz "low swap". Quanto a "adicionar muita troca", não, eu não fiz isso porque não sei como. Essa é precisamente essa questão. Como adiciono espaço de troca? Obviamente, o kernel adiciona espaço de troca automaticamente, mas apenas até um limite. Daí a raiz da questão: como aumentar o limite de espaço de troca do kernel?
Mark Adler

Respostas:

4

Não é a resposta que você pediu, mas se você criar seu próprio arquivo de tamanho apropriado, mapeie-o em seu processo e, em seguida, execute seu cálculo nesse espaço de endereço, que deverá ter o mesmo efeito que um arquivo de troca e você terá a garantia de ter espaço, em vez de competir com outros processos pela RAM / troca disponível.

Também pode ser mais lento, dependendo da frequência com que você sobrescreve os dados, mas deve ser muito mais portátil.

sem data
fonte
2
Boa ideia! Eu tinha grandes esperanças. Infelizmente, eles foram arremessados ​​contra a costa dura da realidade. O processo ainda foi morto pelo kernel por grandes quantidades de troca, exatamente como antes (mensagem do console "baixa troca"), mesmo usando um arquivo que eu havia criado para usar como memória virtual mmap().
Mark Adler #
Desculpe, a maior parte da minha experiência é com Linux. Mas, talvez o problema seja que o kernel não está retornando ao arquivo e mantendo-o na RAM. E se você ligar periodicamente msync()para forçá-lo a fazer isso?
dataless
0

Minhas informações do mac são bastante antigas, pode não haver mais a mágica do kernel para fazer isso. Como tal, sugiro usar o Linux para este programa, onde você pode montar uma pasta ou partição como swap de maneira muito simples.

Elimine as incertezas de usar uma pasta de troca dinâmica. Crie uma partição de troca física (apenas uma partição não formatada vazia, com código de tipo de tabela de disco para troca, no Linux é código hexadecimal 0x82).

  1. Edite o arquivo / etc / rc e encontre o comentário da seção de troca. adicione a linhamount -vat swap
    • significa montar todas as partições de swap no / etc / fstab
  2. corre pdisk /dev/disk? -dump
    • "?" é o número do disco do seu registro hd, o número ao lado da partição swap
  3. Edite ou crie / etc / fstab (provavelmente não existe) e adicione uma linha como /dev/disk?s?? none swap sw 0 0
    • ? é o seu disco.
    • ?? é o número da partição de troca.
  4. reiniciar.
Poder maximo
fonte