Подтвердить что ты не робот

Космические утечки в Haskell

Я читал много раз, что ленивая оценка в Haskell иногда может привести к утечке пространства. Какой код может привести к утечке пространства? Как их обнаружить? И какие меры предосторожности могут быть предприняты частью программиста, чтобы избежать их?

4b9b3361

Ответ 1

Вы получите, вероятно, много ответов, это тот, с которым я столкнулся при попытке сделать какое-то "реальное" приложение. Я использовал многопоточность и некоторые MVars для передачи данных (MVar - это что-то вроде блокированной общей памяти). Моя типичная модель была:

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

А потом, иногда, когда произошло надлежащее условие, я сделал что-то вроде:

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

Проблема состоит в том, что содержание mvar было по существу (0 + 1 + 1 + 1 +....)..., что было довольно интенсивным для чисел, таких как 100k... Этот тип проблемы был довольно распространен в моем код; к сожалению, для многопоточных приложений очень легко попасть в такие проблемы.

Обнаружение... то, что я сделал, - это запуск haskell в режиме, который создает данные о потреблении памяти, запуске и остановке разных потоков и поиске стабильности контура памяти или нет...

Анотомия утечки thunk (с инструкциями по ее отладке)

Пример: Утечка памяти Thunk в результате функции карты

Ответ 2

Я столкнулся с этой проблемой при выполнении рекурсии над большими структурами данных. Застроенные thunks становятся слишком много, а затем вы получаете космическую утечку.

В Haskell вам нужно постоянно знать о возможности пробега в пространстве. Поскольку итерации не существует, в принципе любая рекурсивная функция может генерировать утечку пространства.

Чтобы избежать этой проблемы, memoize рекурсивные функции или переписать их хвостовым рекурсивом.