¿El recolector de basura de MATLAB?

¿Cuál es tu modelo mental de eso? ¿Cómo se implementa? ¿Qué fortalezas y debilidades tiene? MATLAB GC vs. Python GC ?

A veces veo cuellos de botella de rendimiento extraño cuando uso funciones anidadas de MATLAB en un código que, de otro modo, sería inocuo, estoy seguro de que es por GC. Garbage Collector es una parte importante de VM y Mathworks no lo hace público.

¡Mi pregunta es sobre el propio montón de MATLAB y GC! No sobre el manejo de objetos Java / COM / prevención de errores “sin memoria” / asignación de variables de stack.

EDIT: la primera respuesta es en realidad la meta-respuesta “¿Por qué debería importarme?”. Me importa porque GC se manifiesta al implementar la lista vinculada o el patrón MVC .

Esta es la lista de hechos que recopilé. En lugar de GC, el término asignación de memoria (de) parece ser más apropiado en este contexto.

Mi principal fuente de información es el blog de Loren (especialmente sus comentarios) y este artículo de MATLAB Digest.

Debido a su orientación para la computación numérica con posibles conjuntos de datos de gran tamaño, MATLAB hace un trabajo realmente bueno en la optimización del rendimiento de los objetos de la stack, como el uso de operaciones in situ en los datos y la llamada por referencia en los argumentos de la función. También debido a su orientación, su modelo de memoria es fundamentalmente diferente de los lenguajes OO como Java.

MATLAB oficialmente no tenía memoria de montón definida por el usuario hasta la versión 7 (en la versión 6 había funcionalidad de reference no documentada en los archivos schema.m ). MATLAB 7 tiene un montón tanto en forma de funciones anidadas (cierres) como en el manejo de objetos , su implementación comparte los mismos fundamentos. Como nota al margen, OO podría emularse con cierres en MATLAB (interesante para pre-2008a).

Sorprendentemente, es posible examinar todo el espacio de trabajo de la función adjunta capturada por el identificador de función (cierre), ver funciones de función (fhandle) en la Ayuda de MATLAB. Significa que el espacio de trabajo adjunto se está congelando en la memoria. Es por eso que cellfun/arrayfun veces son muy lentos cuando se usan dentro de funciones anidadas.

También hay publicaciones interesantes de Loren y Brad Phelan sobre la limpieza de objetos.

El hecho más interesante sobre la desasignación de heap en MATLAB es, en mi opinión, que MATLAB intenta hacerlo cada vez que se desasigna la stack, es decir, al salir de cada función. Esto tiene ventajas, pero también es una gran penalización para la CPU si la desasignación del montón es lenta. ¡Y en realidad es muy lento en MATLAB en algunos escenarios!

Los problemas de rendimiento de la desasignación de memoria de MATLAB que pueden afectar al código son bastante malos. Siempre me doy cuenta de que involuntariamente introduzco referencias cíclicas en mi código cuando de repente se ejecuta x20 más lento y algunas veces necesita algunos segundos entre dejar la función y regresar a la persona que llama (tiempo dedicado a la limpieza). Es un problema conocido, vea Dave Foti y esta publicación anterior del foro cuyo código se utiliza para hacer que esta imagen visualice el rendimiento (las pruebas se realizan en diferentes máquinas, por lo que la comparación de tiempo absoluta de las diferentes versiones de MATLAB no tiene sentido):

¡El aumento lineal del tamaño de la agrupación para objetos de referencia significa una disminución polinómica (o exponencial) del rendimiento de MATLAB! Para los objetos de valor, el rendimiento es, como se esperaba, lineal.

Teniendo en cuenta estos hechos, solo puedo especular que MATLAB utiliza una forma aún no muy eficiente de conteo de referencias para la desasignación de heap.

EDITAR : Siempre encontré un problema de rendimiento con muchas pequeñas funciones anidadas, pero recientemente noté que al menos con 2006a la limpieza de un solo scope nested con algunos megabytes de datos también es terrible, ¡demora 1.5 segundos en establecer la variable de ámbito nested en vacío!

EDIT 2 : finalmente recibí la respuesta – por el propio Dave Foti . Él reconoce los defectos, pero dice que MATLAB va a mantener su actual enfoque de limpieza determinista.

Leyenda: el tiempo de ejecución más corto es mejor

R2006aR2008aR2009a

MATLAB hace que el espacio de trabajo sea muy claro en el navegador del área de trabajo o con el comando “whos”. Esto le muestra todos los objetos creados por sus comandos y la cantidad de memoria que ocupan.

 feature('memstats') 

le mostrará el bloque contiguo de memoria más grande disponible para MATLAB, lo que significa que es la matriz más grande que puede crear. El uso del comando “borrar” eliminará sincrónicamente esos objetos de la memoria y liberará el espacio que se utilizará nuevamente.

La JVM maneja la recolección de basura solo de elementos de Java. Entonces, si abre un archivo en el editor y lo cierra, Java se encarga de eliminar la ventana y el texto, etc. de la memoria. Si crea un objeto Java en el espacio de trabajo de MATLAB, primero tiene que ser borrado y luego puede ser limpiado por el jvm.

Hay mucha información sobre cómo administrar la memoria del progtwig en nuestra nota técnica: http://www.mathworks.com/support/tech-notes/1100/1106.html

Y recientemente escribí sobre el manejo de la memoria Java en el blog de MATLAB Desktop: http://blogs.mathworks.com/desktop/2009/08/17/calling-java-from-matlab-memory-issues/

Si estás interesado académicamente, qué sucede con la memoria asignada cuando sale una función o cuando cambias el tamaño de una variable … Estoy bastante seguro de que es un secreto comercial y cambia cada versión. Nunca debe notarlo, y si se encuentra con problemas de rendimiento que sospecha que están relacionados con Object Managmenet, presente un ticket de ayuda con soporte técnico: http://www.mathworks.com/support

Parece que estás tratando de construir algún tipo de argumento Python vs MATLAB. No estoy tan interesado en esa discusión.

Una meta-respuesta a su meta-pregunta.

De hecho, es bastante importante que no te importe. Cuando digo eso, no me refiero a limitarlo a la gestión de memoria de MATLAB. Esto se extiende a Python, Java, .NET y cualquier otro lenguaje que haga asignación de memoria dinámica y aún está en desarrollo activo.

Cuanto más sepa sobre el mecanismo actual de administración de la memoria, más probabilidades tendrá de codificar defensivamente contra esa implementación específica, más probable será que no se beneficie de futuras mejoras en el rendimiento. Se pueden encontrar varios buenos ejemplos de esto en el gc de Java redactado hábilmente por Brian Goetz en developerworks.com:

http://www.ibm.com/developerworks/library/j-jtp01274.html

Puedes decir que es importante saberlo. Yo respondo que todo se trata de los requisitos. La pregunta más apropiada es, ¿los idiomas que estoy considerando para mi proyecto satisfacen mis necesidades en términos de rendimiento, esfuerzo de desarrollo, facilidad de mantenimiento, portabilidad, experiencia de mis desarrolladores, etc., etc.?

Nunca he visto un proyecto con un requisito para usar un gc generacional sobre el barrido de marcas sobre el recuento de ref. No espero ver uno pronto.