Sto implementando alcuni algoritmi che funzionano su dati di grandi dimensioni (~ 250 MB - 1 GB). Per questo avevo bisogno di un ciclo per fare un po 'di benchmarking. Tuttavia, nel processo apprendo che F # sta facendo alcune cose sgradevoli, che spero che alcuni di voi possano chiarire.Compilatore F # mantiene in vita gli oggetti morti
Ecco il mio codice (descrizione del problema è al di sotto):
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
Ecco l'output sarà simile:
54000
54000
54000
54000
54000
54000
54000
54000
54000
54000
400000000
800000000
1200000000
Out of memory exception
Così, nel circuito di F # scarta il risultato, ma quando Non sono nel ciclo F # manterrà i riferimenti ai "dati morti" (ho cercato nell'IL, e apparentemente la classe Program ottiene i campi per questi dati). Perché? E posso ripararlo?
Questo codice viene eseguito all'esterno di Visual Studio e in modalità di rilascio.
+1 Grazie, interessante :) La prima soluzione funziona, ma ignorare ignorare non ha aiutato qui. Sono ancora interessato a scoprire perché fa quello che fa, però. –
Interessante ... Mi ha aiutato quando l'ho provato con l'opzione '-O' (per abilitare le ottimizzazioni). –
Strano. Ha funzionato anche qui quando l'ho eseguito al di fuori di Visual Studio. Tuttavia, ora il ciclo ha provocato un'eccezione fuori memoria, ma SOLO se avessi eseguito prima la versione "non-loop":/Immagino che mi limiterò ad attenermi all'ambito locale. –