Я реализую некоторые алгоритмы, которые работают с большими данными (~ 250 МБ - 1 ГБ). Для этого мне понадобился цикл, чтобы провести сравнительный анализ. Однако в процессе я узнаю, что F # делает некоторые неприятные вещи, которые, я надеюсь, некоторые из вас смогут прояснить.
Вот мой код (описание проблемы ниже):
open System
for i = 1 to 10 do
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000 |> ignore
// should force a garbage collection, and GC.Collect() doesn't help either
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
Array2D.zeroCreate 10000 10000 |> ignore
printfn "%d" (GC.GetTotalMemory(true))
Console.ReadLine() |> ignore
Результат будет примерно таким:
54000
54000
54000
54000
54000
54000
54000
54000
54000
54000
400000000
800000000
1200000000
Out of memory exception
Итак, в цикле F # отбрасывает результат, но когда я не нахожусь в цикле, F # будет сохранять ссылки на «мертвые данные» (я просмотрел IL, и, очевидно, класс Program получает поля для этих данных ). Зачем? И могу ли я это исправить?
Этот код выполняется вне Visual Studio и в режиме выпуска.