Компилятор F # поддерживает мертвые объекты

Я реализую некоторые алгоритмы, которые работают с большими данными (~ 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 и в режиме выпуска.

8
задан Lasse Espeholt 12 June 2011 в 16:38
поделиться