¿Por qué la memoria filtrada aparece asignada a kernel_task y por qué OS X no puede, por lo tanto, recolectar basura?

Anteriormente me dijeron que una señal de que alguna aplicación tiene una fuga de memoria es que kernel_tasktiene una gran huella de memoria, comúnmente del orden de gigabytes. Si un error kextestuviera causando este uso de memoria, esperaríamos ver una discrepancia entre la memoria asignada y las que se espera que se asignen, es decir

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

devolvería algo más que las palabras 'Wired' y 'Name'.

Mientras escribía mi tesis, me di cuenta de que cambiar un pdf mientras está abierto en Vista previa a menudo causa que sucedan cosas malas: ocasionalmente, el uso de memoria kernel_taskpuede aumentar a alrededor de ocho gigabytes o más. Si elimino la vista previa, vuelve a la normalidad, al instante . Entonces, obviamente, algo anda mal, y Preview pierde memoria en estas condiciones.

Entonces, mi pregunta es la siguiente: si que un proceso ha perdido RAM a través de un aumento repentino e inesperado en la huella de kernel_task, ¿por qué OS X no puede saber que algo salió mal? Si matar a Preview restaura mi malloc()memoria perdida, ¿por qué Darwin no hace la recolección de basura automáticamente por mí?

¿Tengo un malentendido fundamental de cómo funciona la gestión de memoria?

EDITAR: (15/9/15)

Aquí hay una demostración de lo que estoy hablando. En primer lugar, observo un uso elevado de la memoria kernel_task(tenga en cuenta que la Vista previa está abierta, apenas visible en la parte inferior del Monitor de actividad, con 333 MiB de RAM):

Alto uso de memoria del kernel

Siguiendo los comentarios útiles de Ashley a continuación, averigüemos cuánto está usando cada kext:

$ 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
$

Entonces, no es una gran cantidad. Mi máquina tiene GPU discretas e integradas; sus controladores solo usan unos pocos MiB de RAM con cable. Por mi corazonada, eliminemos Preview y miremos lo que sucede con la huella de memoria de kernel_task:

Killing preview ayuda a las cosas

La vista previa desapareció y la huella de memoria del kernel se redujo drásticamente. Todavía no hay evidencia de un cambio en el uso de kext: la salida del comando anterior no ha cambiado.

Editar : Error informado como No. 22701036. Todavía estoy esperando una respuesta de Apple. No hay nada particularmente interesante si inspeccionas el proceso en ActivityMonitor, pero tal vez me esté perdiendo algo.

Estoy confundido acerca de dos cosas, ¿podría aclarar? 1) Creo que su diffcomando está comparando las columnas Sizey de la salida. Estoy de acuerdo en que es "memoria asignada", pero no creo que "se espere que se asigne" ( lo describe como "La cantidad de bytes cableados de memoria del kernel que ocupa el kext"). 2) ¿Está viendo la discrepancia entre y cuándo tiene el problema con la vista previa? WiredkextstatSizeWiredman kextstatSizeWired
1) Tiene razón: estoy comparando los elementos en Tamaño y Con cable de kextstat. Tengo entendido que si un kext se filtra, entonces los bytes asignados y los que el kernel sabe que están asignados serán diferentes. En este caso, lo puse allí para mostrar que no tengo un kext con fugas, por lo tanto, 2) esto no ocurre cuando Preview come carnero. En cambio, kernel_taskcrece mucho. Intentaré recrear este problema y tomaré una foto :-).
¡Gracias! Espera un segundo: solo estoy escribiendo una respuesta que podría ayudar.

Respuestas (2)

El núcleo de OS X no es basura recolectada; El tiempo de ejecución libkern C++ de IOKit requiere que los desarrolladores administren su propia memoria.

Gestión de memoria Mac

De ¿Cómo funciona la administración de memoria en Mac OS X?

Apple documenta los niveles más bajos de Mach Kernel y el subsistema de memoria virtual bastante bien en la web como parte de su documentación para desarrolladores.

Dado que ese núcleo fue desarrollado por la Universidad Carnegie Mellon , puede encontrar docenas de artículos que lo describen con bastante facilidad.

Otras fuentes

Recolección de basura

La recolección de basura existe en la capa de usuario o aplicación. Incluso en esta capa, la recolección de basura solo ayuda si la aplicación ha liberado todos los reclamos de la memoria. Una dependencia circular puede derrotar la recolección de basura. La recolección de basura en sí misma es un área de investigación en evolución y difícil de acertar .

Informar errores y fugas de memoria

Los errores dentro de OS X perderán memoria. Dado el tamaño del código base, esto es casi seguro.

Informe los errores reproducibles directamente a Apple . Todos los informes de errores ayudan y tal vez su ejemplo sea el que ayude a los ingenieros de Apple a determinar la causa.

Esto es decepcionante, pero indudablemente correcto. Le informé el error a Apple. ¡Simplemente lo encuentro molesto!
Por favor, ¿puede compartir el número de error como una edición de su pregunta? Otros que encuentren útil su pregunta pueden archivar errores duplicados anotando su original. Un montón de errores relacionados ayudará a justificar más tiempo de ingeniería.

Esta es mi suposición, suponiendo que su Mac tenga una GPU integrada (por ejemplo, Intel Iris Graphics).

Cuando tiene su tesis abierta en Vista previa, la memoria de la tarjeta gráfica se usa para contener la imagen ("textura") de la ventana de Vista previa, y quizás también algunas páginas de la tesis fuera de la pantalla pero descodificadas.

Con una tarjeta gráfica integrada, la memoria de video está (¿parcialmente?) ubicada en la RAM del sistema, que se comparte entre la CPU y la GPU. En algunas tarjetas gráficas integradas, la cantidad de RAM del sistema utilizada se asigna dinámicamente (ver Apple HT204349 ).

Supongo que está viendo un error de forma intermitente en el controlador de la tarjeta gráfica y/o en la Vista previa, que no libera la memoria del sistema correctamente cuando la Vista previa vuelve a cargar el PDF de su tesis. (Sin embargo, este error es mitigado por OS X / el controlador libera correctamente la memoria cuando se cierra la vista previa).

Podría intentar mirar el resultado de kextstaty ver si los números en la Sizecolumna aumentan cuando experimenta el problema. Mi teoría es que el aumento de 8 GB que mencionas se deberá al controlador de la tarjeta gráfica.

El siguiente comando (de un comentario sobre esta respuesta relacionada e interesante ) ordena la salida de kextstatpara que sea más fácil ver qué kext está usando la mayor cantidad de memoria (aunque tenga en cuenta que esto se ordena por Wiredcolumna ... hay un encantamiento similar y más simple en este responda con una explicación si desea modificar esto).

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n
Buena suposición, y muchas gracias por una salida ordenada y útil de kextstat. Sin embargo, todavía no parece que eso sea lo que realmente está sucediendo: durante el devorador de vista previa, la huella de memoria de com.apple.nvidia.driver.*no cambió. He editado mi pregunta para reflejar esto.