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

Сбор мусора в Haskell и параллельные вычисления

Большинство языков, использующих сборщики мусора (возможно, все из них), имеют одну серьезную проблему, связанную с параллельными вычислениями: сборщик мусора должен остановить все запущенные потоки, чтобы удалить неиспользуемые объекты. У Haskell есть сборщик мусора. Но из-за чистоты Haskell гарантирует, что никакие вычисления не изменят исходные данные, вместо этого он создает копию, а затем вносит изменения. Полагаю, таким образом, GC не должен останавливать все потоки, чтобы выполнять свою работу. Мне просто интересно: у Haskell такая же проблема с сборкой мусора или нет?

4b9b3361

Ответ 1

Сборщик мусора GHC является параллельным, но не параллельным. Это означает, что он может использовать все потоки для сбора мусора, но для этого нужно остановить все потоки. Одновременная сборка мусора гораздо сложнее реализовать (и, как правило, имеет более высокую производительность).

Несколько иронично, что Haskell действительно использует множество изменяемых объектов, а именно thunks (неоцениваемые выражения). Объекты Mutable не могут быть свободно дублированы (и даже для неизменяемых объектов слишком много дублирования следует держать под контролем).

Для программ, работающих на нескольких ядрах, имеющих действительно параллельный сборщик, было бы неплохо, но вы также можете получить приличную выгоду, сделав кучу локальных сборщиков мусора. Идея состоит в том, что данные, которые не разделяются между несколькими процессорами, могут собираться только владельцем ЦП. Обычно это относится к краткосрочным данным. Саймонс проделал некоторые недавние работы в этой области. См. Их статью "Многоузловая сборка мусора с местными кучами" (PDF). Эта статья также показывает некоторые способы, как вы можете использовать неизменность таким же образом, как вы предлагаете.

Изменить: я забыл упомянуть, что Эрланг в основном делает именно то, что вы предлагаете. Каждый процесс Erlang имеет свою собственную кучу, и отправка сообщения копирует данные из одного процесса в другой. По этой причине каждый процесс Erlang может выполнять собственный GC независимо от всех других процессов. (Недостатком является то, что Erlang не дает вам общую память concurrency.)

Ответ 2

Реализации Seval GC могут выполняться параллельно, не останавливая мир, как вы предлагаете (я думаю, что последние версии JVM для Oracle не останавливают мир и многопоточны, например, и большинство JVM не являются "остановками" -Мировой ").

Вспомните, что реализации GC могут сильно варьироваться от одной языковой реализации к другой.

Существует значительная литература о GC, и все еще много научных работ по параллельной сборке мусора.

Начните с хорошей книги, например справочника GC (Ричард Джонс, Энтони Хоскинг, Элиот Мосс). Или, по крайней мере, wikipedia Страница сбора мусора.

Чисто функциональные языки, такие как Haskell, сильно зависят от очень эффективного GC. Другие языки имеют разные ограничения (например, барьеры для записи имеют меньшее значение с Haskell, чем с Java, но программы Haskell, вероятно, выделяют больше, чем Java).

Для параллельного GC дьявол очень подробно описывает.