Я читал много раз, что ленивая оценка в Haskell иногда может привести к утечке пространства. Какой код может привести к утечке пространства? Как их обнаружить? И какие меры предосторожности могут быть предприняты частью программиста, чтобы избежать их?
Космические утечки в Haskell
Ответ 1
Вы получите, вероятно, много ответов, это тот, с которым я столкнулся при попытке сделать какое-то "реальное" приложение. Я использовал многопоточность и некоторые MVars для передачи данных (MVar - это что-то вроде блокированной общей памяти). Моя типичная модель была:
a <- takeMVar mvar
putMVar mvar (a + 1)
А потом, иногда, когда произошло надлежащее условие, я сделал что-то вроде:
a <- takeMVar mvar
when (a > 10) ....
Проблема состоит в том, что содержание mvar было по существу (0 + 1 + 1 + 1 +....)..., что было довольно интенсивным для чисел, таких как 100k... Этот тип проблемы был довольно распространен в моем код; к сожалению, для многопоточных приложений очень легко попасть в такие проблемы.
Обнаружение... то, что я сделал, - это запуск haskell в режиме, который создает данные о потреблении памяти, запуске и остановке разных потоков и поиске стабильности контура памяти или нет...
Ответ 2
Я столкнулся с этой проблемой при выполнении рекурсии над большими структурами данных. Застроенные thunks становятся слишком много, а затем вы получаете космическую утечку.
В Haskell вам нужно постоянно знать о возможности пробега в пространстве. Поскольку итерации не существует, в принципе любая рекурсивная функция может генерировать утечку пространства.
Чтобы избежать этой проблемы, memoize рекурсивные функции или переписать их хвостовым рекурсивом.