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_pager
diz 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 -S
opçã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.
fonte
malloc
mais 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.malloc()
que isso acontece. Eu estava desviando possíveis comentários sobre alguém pensando que não estou verificando o valor de retornomalloc()
. A propósito, meu objetivo não é falhar antes. Meu objetivo é ter sucesso.Respostas:
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.
fonte
mmap()
.msync()
para forçá-lo a fazer isso?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
).mount -vat swap
pdisk /dev/disk? -dump
/dev/disk?s?? none swap sw 0 0
fonte