Autofac memory leak 的處理方式
問題:原來 Autofac 在 .net 內會有 memory leak 的問題。其原因是由 container 所創建出來的物件,會被 container 一直參考著(即便沒有在使用了)。
底下是自己之前較用的用法。new 完一個 builder 後,註冊相關的物件到介面內,然後產生 container。
var builder = new ContainerBuilder();
builder.RegisterType().As();
var _container = builder.Build();
然後在 resolve 時直接使用 root container 來動作。
var x = _container.Resolve();
但這樣的動作,會讓 .net 的 GC 無法回收。因為這個物件會一直被 root container 參考著。只要一直被參考著,對 .net 來說都算是有在被使用中的物件。而這種物件越積越多的情況下,memroy 就會慢慢的被吃掉,導致 memory leak。
解法: 不要再用 root container 來 resolve 物件。改用 LifeTimeScope 來 resolve 物件。
以上面程式為例,可改寫為底下的方式。
var builder = new ContainerBuilder();
builder.RegisterType().As();
var _container = builder.Build();
var lifetimeScope = _container.BeginLifeTimeScope();
var x = lifetimeScope.Resolve();
LifeTimeScope 在用法上跟 container 差不多,但它的生命週期較短並且也較好控制。 例:在網站的每一個 request 進來都創建一個 LifeTimeScope,在 request 結束的時後,這個 LifeTimeScope 就沒有再被參考到,gc 即可回收到。而由 LifeTimeScope 所創建的物件,也都可一併被回收。
例:也可自行對 LifeTimeScope 作 dispose。這部份雖然 container 也可以,但比較每次都重新創建一個 container,LifeTimeScope 應該是更好的選擇。