首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Funq与子容器的处理

Funq与子容器的处理
EN

Stack Overflow用户
提问于 2013-03-20 06:50:06
回答 2查看 716关注 0票数 4

我们在我们的windows服务中使用Funq来执行一些预定的任务,对于每一轮,我们创建一个子容器来创建我们所有的对象,并在最后处置子容器,我们发现这个子容器创建的元素不是GC,因为根容器有子容器的集合,这些子容器在调用dispose子容器后会留在那里。这段代码重现了我们的问题,并将消耗(并保留) 800MB内存。

对我们来说,这很令人惊讶,这样使用funq是不是错误的模式,在这种情况下,我们应该如何使用它?或者这只是一个bug?

谢谢

代码语言:javascript
复制
public class Dummy
{
    public string Content { get; set; }
    public void Generate(int size)
    {
        this.Content = new string('X', size);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var container = new Container();
        container.RegisterAutoWired<Dummy>().ReusedWithin(ReuseScope.Container);
        int size = 20000;
        for (int i = 0; i < size; i++)
        {
            using (var c = container.CreateChildContainer())
            {
                var d= c.Resolve<Dummy>();
                d.Generate(size);
            }
            PrintInfo(i);
        }

        Console.ReadLine();
    }

    private static void PrintInfo(int i)
    {
        if (i%1000 == 0)
        {
            int divide = 1024*1024;
            GC.Collect();
            var p = System.Diagnostics.Process.GetCurrentProcess();
            Console.WriteLine(p.WorkingSet64/divide + "MB");
            Console.WriteLine(p.PrivateMemorySize64/divide + "MB");
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-03-25 03:00:42

通过查看Funq sources中的Container.cs (最后一次更新是在2011年),我可以断定它泄漏了子容器。

CreateChildContainer方法创建新的容器,将其与父容器连接,并将创建的引用添加到childContainers堆栈。

只有两个地方使用childContainers堆栈:

  • childContainers.Push(child);in Container.CreateChildContainer() (行73)
  • childContainers.Pop().Dispose();in Container.Dispose() (第88行)

因此,如果你创建子容器,然后将其销毁(但不是其父容器)--对被处置的子容器的引用将保留在父容器中,因为没有清理代码可以将被处置的引用从父堆栈中移除。

也许你可以通过创建代理子容器(只有一次),然后从它派生所有真正的子容器来解决这个问题。由于Dispose方法不会将对象转换为不可用状态-您可以通过一遍又一遍地为代理子对象调用Dispose来清理所有子对象:

代码语言:javascript
复制
    var container = new Container();
    container.RegisterAutoWired<Dummy>().ReusedWithin(ReuseScope.Container);
    int size = 20000;
    var proxy = container.CreateChildContainer()
    for (int i = 0; i < size; i++)
    {
        using (proxy)
        using (var c = proxy.CreateChildContainer())
        {
            var d= c.Resolve<Dummy>();
            d.Generate(size);
        }
        PrintInfo(i);
    }
票数 3
EN

Stack Overflow用户

发布于 2014-01-15 20:50:28

这个问题是由于父容器有一个子容器的引用,即使子容器被释放了。垃圾收集器在大多数情况下都工作得很好,但我认为这是最基本的情况。最简单的方法是,如果容器父对象不为空,则从父对象的子集合中删除容器引用。

您可以从this unit test(您的代码片段)和its implementation查看该方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15512035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档