Skip to content

Instantly share code, notes, and snippets.

@vasily-kirichenko
Last active December 13, 2015 20:29
Show Gist options
  • Save vasily-kirichenko/4970648 to your computer and use it in GitHub Desktop.
Save vasily-kirichenko/4970648 to your computer and use it in GitHub Desktop.
// plane function, everything is OK
let rec loop n =
if n % 1000 = 0 then printfn "%d" n
loop (n + 1)
loop 0
// plane function with recursive call from try...with, stack overflow exception after ~12K iterations
let rec loop n =
try
if n % 1000 = 0 then printfn "%d" n
loop (n + 1)
with _ -> ()
loop 0
// subtle case: plane function with implicite try...finally (use keyword), stack overflow exception
let rec loop n =
use d = { new IDisposable with member x.Dispose() = () }
if n % 1000 = 0 then printfn "%d" n
loop (n + 1)
loop 0
// async function without try...with, everything is OK
let rec loop n = async {
if n % 1000 = 0 then printfn "%d" n
return! loop (n + 1)
}
loop 0 |> Async.RunSynchronously
// async function with recursive call from try...with, memory leak ~60B per iteration (!)
let rec loop n = async {
try
if n % 1000 = 0 then printfn "%d" n
return! loop (n + 1)
with _ -> ()
}
loop 0 |> Async.RunSynchronously
// subtle case: async function with implicite try...finally (use keyword), memory leak
let rec loop n = async {
use d = { new IDisposable with member x.Dispose() = () }
if n % 1000 = 0 then printfn "%d" n
return! loop (n + 1)
}
loop 0 |> Async.RunSynchronously
// another subtle case: async function with implicite try...finally (use! keyword), memory leak
let rec loop n = async {
use! d = async { return { new IDisposable with member x.Dispose() = () }}
if n % 1000 = 0 then printfn "%d" n
return! loop (n + 1)
}
loop 0 |> Async.RunSynchronously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment