Ответ 1
Прослеживая код, мы обнаруживаем, что это значение сохраняется в поле closure_env
типа данных PersistentLinkerState
, которое является ClosureEnv
, то есть отображением от имени до HValue
s. Соответствующей функцией в Linker.hs
является
extendLinkEnv :: [(Name,HValue)] -> IO ()
-- Automatically discards shadowed bindings
extendLinkEnv new_bindings =
modifyPLS_ $ \pls ->
let new_closure_env = extendClosureEnv (closure_env pls) new_bindings
in return pls{ closure_env = new_closure_env }
и хотя комментарий указывает, что он должен удалить привязанную привязку, он, по крайней мере, не так, как вы хотите.
Причина в том, что, поскольку AndrewC пишет правильно: хотя обе переменные имеют одинаковое исходное кодовое имя, они отличаются от компилятора (у них есть другой Unique
). Мы можем наблюдать это после добавления некоторой трассировки к указанной выше функции:
*GHCiGC> a <- newForeignPtr nullFunPtr nullPtr
extendLinkEnv [a_azp]
*GHCiGC> a <- return ()
extendLinkEnv [a_aF0]
*GHCiGC> performGC
extendLinkEnv [it_aFL]
Удаление привязок с тем же именем источника на этом этапе должно решить вашу проблему с GC, но я не знаю, компилятор достаточно хорошо, чтобы сказать, что еще сломает. Я предлагаю вам открыть билет, надеюсь, кто-то узнает.
Путаница при привязке к значению
В комментариях, похоже, возникает некоторая путаница в отношении привязок и значений. Рассмотрим этот код:
> a <- return something
> b <- return somethingelse
> a <- return (b+b)
> b <- return anewthing
В текущей реализации куча будет состоять из `
-
something
-
somethingelse
- a thunk, ссылающийся на оператор
(+)
иsomethingelse
-
anewthing
.
Кроме того, среда интерпретатора имеет ссылки на все четыре значения кучи, поэтому ничто не может быть GCed.
Правильно ожидаемое remdezx заключается в том, что GHCi отбросит ссылку на something
и somethingelse
. Это, в свою очередь, позволит системе времени выполнения собирать мусор something
(мы не предполагаем дальнейших ссылок). GHCi все еще ссылается на thunk, который, в свою очередь, ссылается на somethingelse
, поэтому это не будет собирать мусор.
Ясно, что вопрос был очень специфичным для реализации, и вот такой ответ: -)