Memory leaks with ScopedWindsorServiceProvider
Opened this issue · 5 comments
Hi @hikalkan ,
I'm using abp v3.1.2 and asp.net zero v4.6.1. with .net framework 4.6.1 and asp.net core 2.0.
My application run with large memory(about 2G to 4G), I checked it with the memory profiler tool.
and I found the ScopedWindsorServiceProvider have a lot of instances and bytes(see the image).
what's worse, the ScopedWindsorServiceProvider held about 1G instances.
I check the code in this repository, I found the ScopedWindsorServiceProvider implement the IDisposable.but it seems no code invoke the windsor container's Release method to release it.
I read all the code here,I guess I know how to find the problem.
I will check all the call stack for ScopedWindsorServiceProvider.
If I have the result,I will show here.
Hi @hikalkan
I found the problem is ScopedWindsorServiceProvider is resolved, but did not released by the windsor container.
1.
Here is the allocation call stack.
2.
Here is the allocation call stack.
I also changed the test method ResolvingFromScopeAndReleasingShouldWorkForWindsorTransients to test it.
[Fact]
public void ResolvingFromScopeAndReleasingShouldWorkForWindsorTransients()
{
var collection = new ServiceCollection();
collection.AddScoped<MyTestClass2>();
collection.AddTransient<MyTestClass3>();
var serviceProvider = CreateServiceProvider(collection);
serviceProvider.GetService<IWindsorContainer>().Register(Component.For<MyTestClass1>().LifestyleTransient());
var scopeFactory = serviceProvider.GetService<IServiceScopeFactory>();
IServiceProvider scopeServiceProvider;
using (var scope = scopeFactory.CreateScope())
{
scopeServiceProvider = scope.ServiceProvider;
var testObj1 = scope.ServiceProvider.GetService<MyTestClass1>();
testObj1.IsDisposed.ShouldBeFalse();
serviceProvider.GetService<IWindsorContainer>().Release(testObj1);
testObj1.IsDisposed.ShouldBeTrue();
_disposeCounter.Get<MyTestClass1>().ShouldBe(1);
_disposeCounter.Get<MyTestClass2>().ShouldBe(0);
_disposeCounter.Get<MyTestClass3>().ShouldBe(0);
}
Assert.False(_windsorContainer.Kernel.ReleasePolicy.HasTrack(scopeServiceProvider));
_disposeCounter.Get<MyTestClass2>().ShouldBe(1);
_disposeCounter.Get<MyTestClass3>().ShouldBe(1);
}
Hi @hikalkan .
I created a pull request to fix this problem.Please have a look.Thank you.