Anteriormente me dijeron que una señal de que alguna aplicación tiene una pérdida de memoria es que kernel_task
tiene una gran huella de memoria, comúnmente del orden de gigabytes. Si un error kext
causara este uso de memoria, esperaríamos ver una discrepancia entre la memoria asignada y las que se espera asignar, 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 archivo PDF mientras está abierto en Vista previa a menudo hace que sucedan cosas malas: ocasionalmente, el uso de la memoria kernel_task
puede crecer hasta alrededor de ocho gigabytes o más. Si elimino la vista previa, vuelve a la normalidad, al instante . Entonces, obviamente, algo está mal, y Preview está perdiendo memoria en estas condiciones.
Por lo tanto, mi pregunta es la siguiente: si yo sé que un proceso se ha filtrado a través de un carnero aumento repentino e inesperado de la huella de kernel_task
, por qué no pueden OS X saber que algo ha ido mal tiene. Si matar a Preview restaura mi malloc()
memoria faltante , ¿por qué Darwin no hace la recolección de basura de forma automática por mí?
¿Tengo un malentendido fundamental sobre cómo funciona la administración de memoria?
EDITAR: (15/9/15)
Aquí hay una demostración de lo que estoy hablando. En primer lugar, noto un alto uso de memoria por kernel_task
(nota La vista previa está abierta, solo visible en la parte inferior del Monitor de actividad, usando 333 MiB de ram):
Siguiendo los útiles comentarios de Ashley a continuación, descubramos cuánto usa 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 una gran cantidad. Mi máquina tiene GPU discretas e integradas; sus controladores solo usan unos pocos MiB de ram con cable. En mi presentimiento, matemos a Preview y veamos qué sucede con la huella de memoria de kernel_task
:
La vista previa se ha ido, y la huella de memoria del núcleo se ha reducido 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 reportado como No. 22701036. Todavía estoy esperando una respuesta de Apple. No hay nada particularmente interesante si inspecciona el proceso en ActivityMonitor, pero tal vez me falta algo.
fuente
diff
comando está comparando las columnasSize
yWired
de lakextstat
salida. Estoy de acuerdo en queSize
es "memoria asignada", pero no creoWired
que "se espere que se asigne" (loman kextstat
describe como "El número de bytes cableados de memoria del núcleo que ocupa el kext"). 2) ¿Está viendo la discrepancia entreSize
yWired
cuando tiene el problema con la Vista previa?kextstat
. Entiendo que si un kext tiene fugas, entonces los bytes asignados y los que el núcleo 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 ram. En cambio,kernel_task
crece mucho. Trataré de recrear este problema y tomar una foto :-).Respuestas:
El núcleo de OS X no es la recolección de basura; Ikerit libkern C ++ Runtime requiere que los desarrolladores administren su propia memoria.
Gestión de memoria de Mac
De ¿Cómo funciona la gestión de memoria en Mac OS X?
Otras fuentes
Wikipedia analiza la gestión de memoria de Mac OS .
Nota de soporte de Apple: use el Monitor de actividad para leer la memoria del sistema y determinar cuánta RAM se está usando
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 a la memoria. Una dependencia circular puede vencer la recolección de basura. La recolección de basura en sí es un área de investigación en evolución y difícil de acertar .
Informar errores y fugas de memoria
Los errores en OS X perderán memoria. Dado el tamaño de la base del código, esto es casi seguro.
Por favor , informe de errores reproducibles directamente a Apple . Cada informe de error ayuda y quizás su ejemplo sea el que ayude a los ingenieros de Apple a determinar la causa.
fuente
Aquí está 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 mantener la imagen ("textura") de la ventana Vista previa, y quizás también algunas páginas fuera de la pantalla pero decodificadas de la tesis.
Con una tarjeta gráfica integrada, la memoria de video se encuentra (¿parcialmente?) 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 (consulte Apple HT204349 ).
Supongo que está viendo de forma intermitente un error en el controlador de la tarjeta gráfica y / o Vista previa, que no libera la memoria del sistema correctamente cuando Vista previa vuelve a cargar su PDF de tesis. (Sin embargo, este error es mitigado por OS X / el controlador libera correctamente la memoria cuando se cierra la vista previa).
Puede intentar ver la salida de
kextstat
y ver si los números en laSize
columna aumentan cuando experimenta el problema. Mi teoría es que el aumento de 8GB que mencionas se debe al controlador de la tarjeta gráfica.El siguiente comando (de un comentario sobre esta respuesta relacionada e interesante ) ordena la salida de
kextstat
para que sea más fácil ver qué kext está usando más memoria (aunque tenga en cuenta que esto ordena porWired
columna ... hay un encantamiento similar y más simple en este responda con una explicación si desea modificar esto).fuente
kextstat
. Sin embargo, todavía no parece que eso sea lo que realmente está sucediendo: durante el engullido de Vista previa, la huella de memoria decom.apple.nvidia.driver.*
no cambió. He editado mi pregunta para reflejar esto.