2011-10-14 13 views
18

Lo he leído muchas veces que la evaluación perezosa en Haskell a veces puede dar lugar a fugas de espacio. ¿Qué tipo de código puede conducir a fugas de espacio? ¿Cómo detectarlos? ¿Y qué precauciones puede tomar parte de un programador para evitarlas?Fugas de espacio en Haskell

+7

Eche un vistazo al [Space leak zoo] de Edward Z. Yang (http://blog.ezyang.com/2011/05/space-leak-zoo/). –

Respuesta

12

Probablemente obtendrá muchos respuestas, esta es la que me he encontrado al intentar hacer alguna aplicación del "mundo real". Estaba usando multihilo y algunos MVars para pasar datos (MVar es algo así como la memoria compartida bloqueada). Mi patrón típico era:

a <- takeMVar mvar 
putMVar mvar (a + 1) 

Y entonces, sólo a veces, cuando una condición adecuada sucedió que hice algo como:

a <- takeMVar mvar 
when (a > 10) .... 

El problema es que el contenido de mvar era esencialmente (0 + 1 + 1 + 1 + ....) ... que fue bastante intensivo para números como 100k ... Este tipo de problema era bastante generalizado en mi código; desafortunadamente para aplicaciones de subprocesamiento múltiple es muy fácil entrar en tales problemas.

Detectando ... lo que me estaba empezando Haskell en el modo que produce datos sobre el consumo de memoria, iniciar y detener diferentes hilos y mirando si el consumo de memoria es estable o no ...

Anotomy of a thunk leak (with instructions how to debug it)

Un ejemplo: Thunk memory leak as a result of map function

4

Me he encontrado con este problema al hacer recursividad en estructuras de datos de gran tamaño. Los thunks acumulados llegan a ser demasiado y luego obtienes una pérdida de espacio.

En Haskell, debe ser constantemente consciente de la posibilidad de encontrarse con una fuga de espacio. Como la iteración no existe, básicamente cualquier función recursiva tiene el potencial de generar una fuga de espacio.

Para evitar este problema, memorice las funciones recursivas o rescrínelas recursivamente.