Я реализую некоторые алгоритмы, которые работают с большими данными (~ 250 МБ - 1 ГБ). Для этого мне понадобился цикл для проведения бенчмаркинга. Однако в процессе я узнаю, что F # делает некоторые неприятные вещи, которые, я надеюсь, некоторые из вас могут прояснить.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 и в режиме деблокирования.
+1 Спасибо, интересно :) Первое решение работает, но игнорировать игнорирование здесь не помогло. Меня все еще интересует, почему он делает то, что он делает. –
Интересно ... Это помогло, когда я попробовал это с опцией '-O' (чтобы включить оптимизацию). –
Странно. Он работал и здесь, когда я запускал его за пределами Visual Studio. Однако теперь цикл вызвал исключение из памяти, но ТОЛЬКО, если я сначала запустил «non-loop» версию:/Думаю, я просто буду придерживаться локальной области. –