应该被处理的缓存对象,内存泄漏
本文关键字:对象 内存 泄漏 缓存 处理 | 更新日期: 2023-09-27 18:15:27
内存泄漏时,没有对象在weakreferencecollection内部处理,我做错了什么,或者有一个巨大的错误在ninject?
当内核被销毁时,所有的引用都被销毁,从弱引用集合中,但是在这个循环中,即使没有来自代码的引用,内存也会爆炸。
public class Program
{
private StandardKernel kernel;
private static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false });
kernel.Bind<Root>().ToSelf();
kernel.Bind<Foo>().ToSelf().InCallScope();
while (true)
{
Process();
Thread.Sleep(500);
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
public void Process()
{
Root root = kernel.Get<Root>();
Root root2 = kernel.Get<Root>();
}
public class Root
{
private Foo _test;
public Root(Foo foofac)
{
Id = Guid.NewGuid();
_test = foofac;
}
protected Guid Id { get; set; }
}
public class Foo
{
}
}
<标题> 更新
我尝试了命名作用域,甚至使用了一个工厂,就像在例子中:http://www.planetgeek.ch/2012/04/23/future-of-activation-blocks/但是,在内存分析器中,弱引用收集仍然会随着时间的推移而爆炸,这并不好……我当前的测试代码是:
public class Program
{
private StandardKernel kernel;
private static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false });
kernel.Load<FuncModule>();
kernel.Bind<IRootFactory>().ToFactory();
var scopeParameterName = "scopeRoot";
kernel.Bind<Root>().ToSelf().DefinesNamedScope(scopeParameterName);
kernel.Bind<Foo>().ToSelf().InNamedScope(scopeParameterName);
while (true)
{
Process();
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(500);
}
}
public void Process()
{
Root root = kernel.Get<IRootFactory>().CreateRoot();
Root root2 = kernel.Get<IRootFactory>().CreateRoot();
}
public class Root
{
private Foo _test;
public Root(Foo foofac)
{
Id = Guid.NewGuid();
_test = foofac;
}
protected Guid Id { get; set; }
}
public class Foo
{
}
public interface IRootFactory
{
Root CreateRoot();
}
}
标题>
这需要时间,并且不打算是确定性的-请参阅实际的impl代码和缓存和收集文章。
在您的示例中,您应该等待等待Ninject release机制被触发(关闭定时器IIRC)。它没有做的一件事是在GC发生时同步地Dispose和Release。
底线是你最好通过IResolutionRoot.Release
或与InRequestScope
相关的命名作用域来确定发布。
不是我推荐使用它,但GC.Collect()
是一种异步机制。调用它只会触发GC发生,而不会等待GC完成。
GC.WaitForPendingFinalizers()
。