Причиной такого поведения является то, что компилятор F # ведет себя иначе в глобальной области видимости, чем в локальной области видимости.Переменная, объявленная в глобальной области видимости, превращается в статическое поле.Объявление модуля - это статический класс с объявлениями let
, скомпилированными как поля / свойства / методы.
Самый простой способ решить проблему - написать код в функции:
let main () =
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
// (...)
Console.ReadLine() |> ignore
main ()
... но почему компилятор объявляет поля, когда вы не используете значение и просто ignore
оно?Это довольно интересно - функция ignore
- это очень простая функция, которая встроена, когда вы ее используете.Декларация let inline ignore _ = ()
.При вставке функции компилятор объявляет некоторые переменные (для хранения аргументов функции).
Итак, еще один способ исправить это - пропустить ignore
и написать:
Array2D.zeroCreate 10000 10000
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000
printfn "%d" (GC.GetTotalMemory(true))
// (...)
Вы получите некоторые предупреждения компилятора, потому что результат выражения не unit
,но это будет работать.Однако использование некоторой функции и написание кода в локальной области видимости, вероятно, более надежно.