Por que a memória vazada parece alocada ao kernel_task e por que o OS X não pode, portanto, coletá-lo com lixo

11

Foi-me dito anteriormente que um sinal de que algum aplicativo tem um vazamento de memória é que kernel_taskpossui um grande espaço de memória, geralmente da ordem de gigabytes. Se um erro kextestivesse causando esse uso de memória, esperaríamos ver uma discrepância entre a memória alocada e a que seria esperada, ou seja,

diff <(kextstat|tr -s ' ' | cut -d ' ' -f 5) <(kextstat| tr -s ' ' | cut -d ' ' -f 6) 

retornaria algo diferente das palavras 'Wired' e 'Name'.

Enquanto escrevia minha tese, notei que alterar um pdf enquanto ele está aberto no Preview geralmente causa coisas ruins: ocasionalmente, o uso de memória kernel_taskpode aumentar para cerca de oito gigabytes ou mais. Se eu matar a visualização, ela voltará ao normal instantaneamente . Então, obviamente, algo está errado - e o Preview está vazando memória nessas condições.

Portanto, minha pergunta é a seguinte: se eu sei que um processo vazou de memória RAM através de um aumento repentino e inesperado na área de cobertura kernel_task, por que o OS X não pode saber que algo deu errado? Se matar o Preview restaura minha malloc()memória perdida , por que Darwin não faz a coleta de lixo automaticamente para mim?

Tenho um mal-entendido fundamental de como o gerenciamento de memória funciona?

EDIT: (15/9/15)

Aqui está uma demonstração do que estou falando. Antes de tudo, noto alto uso de memória kernel_task(observe que a visualização está aberta, visível apenas na parte inferior do Activity Monitor, usando 333 MiB de memória ram):

Alto uso de memória do kernel

Seguindo as observações úteis de Ashley abaixo, vamos descobrir quanto cada kext está usando:

$ kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

...
...
...
   1249280 com.apple.driver.DspFuncLib
   1769472 com.apple.nvidia.driver.NVDAGK100Hal
   2629632 com.apple.nvidia.driver.NVDAResman
   6184960 com.apple.driver.AirPort.Brcm4360
$

Então, não é uma quantidade enorme. Minha máquina possui GPUs discretas e integradas; seus drivers estão usando apenas alguns MiB de ram com fio. No meu palpite, vamos matar o Preview e ver o que acontece com a pegada de memória de kernel_task:

Matar a visualização ajuda as coisas

A visualização sumiu e a pegada de memória do kernel caiu drasticamente. Ainda não há evidência de uma alteração no uso do kext: a saída do comando acima é inalterada.

Edit : Bug relatado como No. 22701036. Ainda estou esperando por uma resposta da apple. Não há nada particularmente interessante se você inspecionar o processo no ActivityMonitor, mas talvez esteja faltando alguma coisa.

Landak
fonte
Estou confuso sobre duas coisas - você poderia esclarecer? 1) Acho que seu diffcomando está comparando as colunas Sizee Wiredda kextstatsaída. Concordo que Sizeseja "memória alocada", mas não acho que Wired"seja alocado" (a man kextstatdescreve como "O número de bytes com fio da memória do kernel que o kext ocupa"). 2) Você está vendo a discrepância entre Sizee Wiredquando tem o problema com a Visualização?
Ashley
1) Você está certo - estou comparando os elementos em Tamanho e Ligação de kextstat. Meu entendimento é que, se um kext estiver vazando, os bytes alocados e os que o kernel sabe que estão alocados serão diferentes. Nesse caso, coloquei isso lá para mostrar que não tenho um kext com vazamento - então, 2) isso não ocorre quando o Preview come carneiro. Em vez disso, kernel_taskcresce muito. Vou tentar recriar esse problema e tirar uma foto :-).
Landak 15/09/15
Obrigado! Espere um segundo: estou escrevendo uma resposta que pode ajudar.
Ashley

Respostas:

6

O núcleo do OS X não é coletado como lixo; O libkern C ++ Runtime do IOKit requer que os desenvolvedores gerenciem sua própria memória.

Gerenciamento de memória Mac

De Como o gerenciamento de memória funciona no Mac OS X?

A Apple documenta os níveis mais baixos do Mach Kernel e do subsistema de memória virtual bastante bem na Web como parte da documentação do desenvolvedor.

Desde que o kernel foi desenvolvido pela Carnegie Mellon University , você pode encontrar dezenas de artigos descrevendo-o com bastante facilidade.

Outras fontes

Coleta de lixo

A coleta de lixo existe na camada de usuário ou aplicativo. Mesmo nessa camada, a coleta de lixo só ajuda se o aplicativo tiver liberado todas as declarações na memória. Uma dependência circular pode derrotar a coleta de lixo. A coleta de lixo em si é uma área de pesquisa em evolução e difícil de acertar .

Relatar bugs e vazamentos de memória

Os erros no OS X estão vazando memória. Dado o tamanho da base de código, isso é quase certo.

Por favor, reporte erros reproduzíveis diretamente à Apple . Todo relatório de bug ajuda e talvez o seu exemplo seja o que ajuda os engenheiros da Apple a identificar a causa.

Graham Miln
fonte
Isso é decepcionante, mas sem dúvida correto. Eu relatei o bug para a Apple - acho isso irritante!
Landak 18/09/2015
2
Você pode compartilhar o número do bug como uma edição da sua pergunta. Outras pessoas que acham sua pergunta útil podem arquivar bugs duplicados, observando o original. Uma pilha de bugs relacionados ajudará a justificar mais tempo de engenharia.
Graham Miln 19/09/15
4

Aqui está o meu palpite, supondo que o seu Mac tenha uma GPU integrada (por exemplo, Intel Iris Graphics).

Quando sua tese é aberta na Visualização, a memória da placa gráfica é usada para reter a imagem ("textura") da janela Visualização, e talvez também algumas páginas fora da tela, mas decodificadas da tese.

Com uma placa de vídeo integrada, a memória de vídeo está (parcialmente?) Localizada na RAM do sistema, que é compartilhada entre a CPU e a GPU. Em algumas placas gráficas integradas, a quantidade de RAM do sistema usada é alocada dinamicamente (consulte Apple HT204349 ).

Eu acho que você está vendo intermitentemente um erro no driver da placa gráfica e / ou no Preview, que não está liberando a memória do sistema corretamente quando o Preview recarrega o PDF da sua tese. (No entanto, esse bug é atenuado pelo OS X / o driver libera corretamente a memória quando a Visualização é encerrada.)

Você pode tentar examinar a saída de kextstate verificar se os números na Sizecoluna aumentam quando o problema ocorre. Minha teoria é que o aumento de 8 GB que você mencionou será devido ao driver da placa de vídeo.

O comando a seguir (de um comentário sobre esta resposta relacionada e interessante ) classifica a saída de kextstatpara facilitar a visualização de qual kext está usando mais memória (embora observe isso classificado pela Wiredcoluna ... há um encantamento semelhante e mais simples neste responda com uma explicação se desejar ajustar isso).

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n
Ashley
fonte
Bom palpite - e muito obrigado por uma saída útil e classificada de kextstat. No entanto, ainda não parece que é isso o que realmente está acontecendo: durante o processo de visualização, a pegada de memória com.apple.nvidia.driver.*permaneceu inalterada. Eu editei minha pergunta para refletir isso.
Landak 15/09/15