应该被处理的缓存对象,内存泄漏

本文关键字:对象 内存 泄漏 缓存 处理 | 更新日期: 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()