2017-04-06 53 views
1

我試圖調試我的應用程序中的內存泄漏(請參閱相關的question),並且遇到了一個微笑錯誤的行爲。IServiceProvider垃圾收集/處置

在此代碼(簡化的片斷,當然):

while (true) 
    { 
     using (var context = _serviceProvider.GetRequiredService<IDataContext>()) 
     { 
      Console.WriteLine("Hello"); 
     } 
    } 

內存消耗的增長迅速

如果我註釋掉服務產卵,內存消耗是穩定的。

while (true) 
    { 
     // using (var context = _serviceProvider.GetRequiredService<IDataContext>()) 
     // { 
      Console.WriteLine("Hello"); 
     // } 
    } 

服務註冊爲短暫

我的理解是,using聲明負責處理一項服務。在while的範圍內創建var context,並且應在新迭代開始時銷燬。

我的第一個想法是,GC只是沒有足夠頻繁地工作,但當消耗的內存量增加時頻率不會增加?

爲什麼我錯了?

+0

GC是否收集過? – khargoosh

+0

@ khargoosh它應該但似乎並不。問題是爲什麼。 –

+0

是否有可能'_serviceProvider'沒有正確實現'IDisposable'或不釋放任何資源?你有沒有在任何時候收到異常? – khargoosh

回答

3

經過幾天的戰鬥,我最終得出了答案。總之,問題在於微軟DI容器沒有配置瞬態服務,它保留了對它們的引用。

以下是github上的相應issue

開發人員不打算修復它,因爲修復的成本(複雜性和冒險性)超過了好處。

建議的解決方法是使用作用域服務代替瞬態之一。

以下是一個示例代碼,詳見issue

using (var scope = serviceProvider.CreateScope()) 
using (var context = scope.ServiceProvider.GetRequiredService<IDataContext>()) 
{ ... }