【问题标题】:Garbage Collection for mutually referenced objects in C#C#中相互引用对象的垃圾收集
【发布时间】:2012-07-21 10:02:58
【问题描述】:

当然,这个问题之前已经被问过,但我找不到任何关于这个问题的线索,所以指向已回答问题的链接也会有所帮助:

我有一个卷类 (VoxelVolume),其中包含一组切片 (Slice)。

public class VoxelVolume
{
    Slice[] mySlices;

    public VoxelVolume(int noOfSlices)
    {
        mySlices = new Slice[noOfSlices];

        for (int i = 0; i < mySlices.Length; i++)
        {
            mySlices[i] = new Slice(this);
        }
    }
}

卷知道切片,切片知道卷:

public class Slice
{
    public VoxelVolume Volume
    {
        get;
        private set;
    }

    public Slice(VoxelVolume aVolume)
    {
        Volume = aVolume;
    }
}

问题在于卷永远不会被垃圾收集,因为存在相互对象引用。出于这个原因,我将切片到卷的引用实现为 WeakReference:

public class Slice
{
    WeakReference myVolume;

    VoxelVolume Volume
    {
        get
        {
            return (VoxelVolume)myVolume.Target;
        }
    }

    public Slice(VoxelVolume aVolume)
    {
        myVolume = new WeakReference(aVolume);
    }
}

现在垃圾收集工作了,但需要额外的 WeakReference。由于我可以拥有数千个切片,因此 WeakReferences 的工作量非常大。

编辑:首先它没有出现,但由于我们使用了大量内存,所以出现了“内存泄漏”。因此,我们使用 JetBrains dotTrace 查看了引用和可用的对象。在那里,我们看到有很多对象可用,尽管它们不再使用。正如我之前所说,使用 Wea​​kReference 解决了这个问题。

问题是,TreeView 是如何解决这些问题的,因为 TreeNode 也有 TreeView 的知识。

您知道合适的解决方案吗?

谢谢 马丁

【问题讨论】:

  • .NET 垃圾收集器正确处理对象图中的未引用循环。例如。如果对象 A 引用对象 B 和 B 引用 A,前提是 A 和 B 都不能从 GC 根访问,即使它们相互引用,它们也会被收集。你如何确定你的卷没有被收集?
  • 你好,铱星。你说的对。请在上面的文本中查看我的编辑。
  • 由于 WeakReference 版本没有出现此问题,这表明您的切片仍然可以通过某种方式访问​​。 dotTrace 是否给出了关于什么(除了 VoxelVolumed)可能引用切片的任何指示?
  • 我会再看一遍。如果我知道更多,我会在这里添加评论。谢谢。

标签: c# garbage-collection weak-references


【解决方案1】:

问题在于卷永远不会被垃圾收集,因为存在相互对象引用。

只有当 something 可以访问SliceVoxelVolume 时,这才会成为问题。当您不再引用任何一个对象时,它们都将有资格进行垃圾收集。对象中的循环在 .NET 中不是问题,因为它不使用引用计数。

当然,您确实需要确保您没有从任何 GC 根中引用 SliceVoxelVolume。你还没有真正给我们足够的背景来了解这里发生了什么。

【讨论】:

  • 嗨乔恩。我在文本中进行了编辑,使用 JetBrains dotTrace 进行了调试。正如我从您的所有帖子中看到的那样,循环引用可以由 GC 解决。所以看来我的代码有问题。
【解决方案2】:

CLR 中的 GC 引擎应该收集循环引用的对象,只要没有其他人引用它们中的任何一个。

当您决定不再需要它们时,实现 IDisposable 模式并清除引用也是一个好主意。它可以减少大量内存泄漏的机会,以防坏事保留您没有注意到的引用。

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多