下午好。內存泄漏 - Ninject,WCF,WEBApi,ChannelFactory
我正面臨着內存泄漏的問題,我想我知道發生這種情況的地方,但不知道我需要做什麼來修復它!希望你們能再次拯救我。
我真的已經嘗試谷歌它(很多),但我發現或測試結果沒有實際工作。
我使用了很多功能,但我不得不遵循客戶IT部門的一些架構規則,因此不能考慮這個主題,就像不使用Ninject或不使用WCF一樣例。我可以做什麼(也許我需要)是改變他們的實施方式。
這就是說,讓我們去看炸彈。
在我的項目中,表示層託管在一個服務器中,WCF服務及其所有依賴項(域,存儲庫等)位於另一個服務器中。
問題出在WCF服務器上,該服務器增加了從演示文稿到服務的每個請求的內存使用量,並且不會釋放此內存,直到服務器內存達到極限,並且服務器需要重新啓動,或者IIS應用程序池將被重新啓動。
下面所使用的技術:
領域模型,WCF,MVC4使用Web API,Ninject 3.2 MVC和WCF,AutoMapper映射從域DTO和扭轉,資源庫和NHibernate。
我已經檢查了Repository和NHibernate圖層,它們正確地處理它們的對象。
我使用Ninject注入WCF中表現爲按照App_Start:
public class NinjectConfiguration
{
public void Configure(IKernel container)
{
AddBindings(container);
var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
private void AddBindings(IKernel container)
{
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>());
// ...
}
public TService CreateChannel<TService>() where TService : class
{
var factory = new ChannelFactory<TService>(string.Empty);
factory.Open();
return factory.CreateChannel();
}
}
呈現的Web.Config端點配置:
<system.serviceModel>
<client>
<endpoint address="http://MyEndPoint/PersonService.svc" binding="wsHttpBinding" bindingConfiguration="BindClientConfig" contract="MyContract.IPersonService" />
</client>
<bindings>
<wsHttpBinding>
<binding name="BindClientConfig" maxReceivedMessageSize="2147483647" sendTimeout="00:01:00"></binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
我的WebAPI配置:
public class PersonController : ApiController
{
IPesrsonService _personService;
public PersonController(IPesrsonService personParam) { ... }
//Gets, Post, Put, Delete here and functional
protected override void Dispose(bool disposing)
{
if (_personService != null)
{
_personService.Dispose(); //This point is reached
}
base.Dispose(disposing);
}
}
而我的WCF處置(合同實現IDisposable):
public class PersonService : IPersonService
{
private IPersonDomain _personDomain;
public PersonService(IPersonDomain personDomainParam) { ... }
//...
protected virtual void Dispose(bool disposing) { ... }
public void Dispose()
{
Dispose(true); //This point is NEVER reached
GC.SuppressFinalize(this);
}
}
理論上,來自WebAPI的_personService.Dispose必須從WCF調用Dispose,但此Dispose WCF永遠不會到達。我可以從WCF獲得其他任何方法,但Dispose,我不能。
我的猜測是我錯過了Ninject配置中的一些東西,它創建了這個非託管孔。
看起來,表示層並沒有真正關閉到WCF的連接,這樣,終端在通信的另一端(WCF服務器)永遠打開並保留分配的內存。
我已經試圖改變NinjectConfiguration如下,但沒有成功:
private void AddBindings(IKernel container)
{
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>());
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).InScope(ctx => HttpContext.Current);
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).OnDeactivation(CloseServiceConnection);
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).OnDeactivation(CloseServiceConnection<IPersonService>);
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).InScope(ctx => HttpContext.Current).OnDeactivation(CloseServiceConnection);
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).InScope(ctx => HttpContext.Current).OnDeactivation(CloseServiceConnection<IPersonService>);
container.Bind<IPersonService>().ToMethod(ctx => CreateChannel<IPersonService>()).InScope(ctx => OperationContext.Current).OnDeactivation(CloseServiceConnection<IPersonService>);
}
public static void CloseServiceConnection<T>(T service)
{
(service as IDisposable).Dispose();
}
也許CreateChannel從NinjectConfiguration類可以用另一種方式來創建這樣我就可以調用channel.Close(),但我不知道該怎麼做。
但是,這一切只是一個猜測。你發佈的一切,我會嘗試。
我感謝任何幫助,並非常感謝你的時間。
埃萊克圭多林
我會建議爲每個服務調用創建一個新工廠可能是問題的一部分。 – sga101 2014-10-29 17:12:27
真正的混亂是因爲我不知道如何在這種情況下調用WCF配置。我不知道它是Ninject的配置,還是我創建工廠的方式,我不知道如何從工廠調用Close(),這可以調用此函數。 在演示服務器中,內存很好,並處理它們的對象。 – 2014-10-29 17:29:55
我沒有得到正確的結果:'PersonController'你想通過WCF *調用'IPersonService.Dispose()'*?或者換句話說:一個進程(其中'PersonController'住在哪裏)正在處理另一個進程的對象(其中'IPersonService'住在哪裏)? – BatteryBackupUnit 2014-10-30 07:16:15