F#のasynchronous workflowでメモリーリーク

お客さんにリリース済みのAzure上で動くものでいい感じにメモリリークしていて困ってたんですが、ダンプ取ってやっとわかりましたよ・・・

原因としてはasync{}で再帰ループしてたんですが、ループをtry-withの中でしてたから。考えてみればcatch時に継続するコードをheap上に保持するんだからそれはリークするよね・・・

下の方も同じようなことをしたらしい。
http://moiraesoftware.com/blog/2011/12/11/fixing-a-hole/

自分はwindbgで解析したんですが、上の方の使ってるツール、良く見てないですが、便利そうですね・・・

//リークを起こす
let rec loop i=async{
    try 
        printfn "%s %d"(System.DateTime.Now.ToString()) i
        return! loop (i+1)
    with e->()
    }
loop 0
|>Async.Start

//リーク起こさない
let rec loop2 i=async{
    try 
        printfn "%s %d"(System.DateTime.Now.ToString()) i
    with e->()
    return! loop2 (i+1)
    }
loop2 0
|>Async.Start