Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 列表对象的垃圾收集_C#_Garbage Collection_Red Gate Ants - Fatal编程技术网

C# 列表对象的垃圾收集

C# 列表对象的垃圾收集,c#,garbage-collection,red-gate-ants,C#,Garbage Collection,Red Gate Ants,请问清理和处置物品清单中收集的物品的效率如何 是通过调用List.Clear方法自动清理它收集的所有对象吗 例如,考虑下面的例子 public partial class Form1 : Form { FontCollection m_fontCollection; public Form1() { InitializeComponent(); } private void button1_Click(object sender, Ev

请问清理和处置物品清单中收集的物品的效率如何

是通过调用List.Clear方法自动清理它收集的所有对象吗

例如,考虑下面的例子

public partial class Form1 : Form
{
    FontCollection m_fontCollection;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        m_fontCollection = new FontCollection();
        for (int i = 0; i < 5000; i++)
        {
            Font font = new Font("Arial", 23);

            FontImpl impl = new FontImpl(font, Color.Black);
            impl.AfterChange += 
                new FontImpl.AfterChangeHandler(impl_AfterChange);

            m_fontCollection.Add(impl);
        }

        m_fontCollection.Dispose();
        MessageBox.Show("TakeSnap");
    }

    void impl_AfterChange()
    {
        throw new NotImplementedException();
    }
}

public class FontCollection : IEnumerable, IDisposable
{
    IList<FontImpl> m_Implementation = new List<FontImpl>();

    internal void Add(FontImpl impl)
    {
        this.m_Implementation.Add(impl);
    }

    public IEnumerator GetEnumerator()
    {
        return this.m_Implementation.GetEnumerator();
    }

    public void Dispose()
    {
        m_Implementation.Clear();
        m_Implementation = null;
    }
}

public class FontImpl
{
    private Font m_Font;
    private Color m_color;

    public FontImpl(Font newFont, Color newColcor)
    {
        m_Font = newFont;
        m_color = newColcor;
    }

    public event AfterChangeHandler AfterChange;

    public delegate void AfterChangeHandler();
}

当我运行上面的应用程序ANTS memory profiler时,我可以看到内存泄漏Font和FontFamily,我无法上传屏幕以及如何删除这些泄漏。一般来说,您不必担心垃圾收集,也不必担心它何时发生。当一个对象没有引用时,它就有资格使用GC

然而,你应该注意的是物体。完成IDisposable对象后,您确实需要对其调用Dispose。如果对象位于function的局部范围内,则使用块可以简化此操作:

using (var resource = new SomeIDisposable()) {
    // use resource

    // resource.Dispose() is automatically called, *even if* an exception
    // is thrown.
}
您可能会导致内存泄漏,最终导致对对象的挂起引用,从而防止对象被垃圾收集。最常见的原因是事件处理程序。当您使用对象B上的事件处理程序订阅对象A公开的事件时,A获取对B的引用:

通常,当b超出范围时,它引用的对象将有资格进行垃圾收集。不过在本例中,b连接到成员变量_a发布的事件,这导致_a获得对b的引用。现在有一个关于b的突出引用,它是不可能被清除的,而b是不符合GC的。这是内存泄漏


1在这种情况下,如果/当触发事件处理程序时,对b的唯一引用是该指针。

一般来说,您不需要担心垃圾收集以及垃圾收集何时发生。当一个对象没有引用时,它就有资格使用GC

然而,你应该注意的是物体。完成IDisposable对象后,您确实需要对其调用Dispose。如果对象位于function的局部范围内,则使用块可以简化此操作:

using (var resource = new SomeIDisposable()) {
    // use resource

    // resource.Dispose() is automatically called, *even if* an exception
    // is thrown.
}
您可能会导致内存泄漏,最终导致对对象的挂起引用,从而防止对象被垃圾收集。最常见的原因是事件处理程序。当您使用对象B上的事件处理程序订阅对象A公开的事件时,A获取对B的引用:

通常,当b超出范围时,它引用的对象将有资格进行垃圾收集。不过在本例中,b连接到成员变量_a发布的事件,这导致_a获得对b的引用。现在有一个关于b的突出引用,它是不可能被清除的,而b是不符合GC的。这是内存泄漏


1在这种情况下,如果/当触发事件处理程序时,对b的唯一引用是该指针。

您不需要在类上实现IDisposable。通常,类需要实现IDisposable的唯一时间是当它包含需要处理的其他类时,例如数据库和网络连接以及非托管对象


在您的示例中,您可能会考虑在Muto1LCKIT中考虑MyFunCu藏是一个本地变量,因为您完全在该方法中创建和处理它。如果您将其设置为本地,那么一旦按钮1\u单击退出,它将被垃圾收集。。。前提是没有剩余的引用,而在本例中确实没有。

您不需要在类上实现IDisposable。通常,类需要实现IDisposable的唯一时间是当它包含需要处理的其他类时,例如数据库和网络连接以及非托管对象


在您的示例中,您可能会考虑在Muto1LCKIT中考虑MyFunCu藏是一个本地变量,因为您完全在该方法中创建和处理它。如果您将其设置为本地,那么一旦按钮1\u单击退出,它将被垃圾收集。。。前提是没有剩余的引用,而在本例中确实没有。

清除只会从列表中删除所有内容。在本例中,您有一个IDisposable对象的列表,需要对列表中的所有项调用Dispose。打电话澄清并不能做到这一点

FontImpl应该实现IDisposable,因为它管理IDisposable对象:

 public void Dispose() {
      if (m_Font != null) {
          m_Font.Dispose();
          m_Font = null;
      }
 }
您的FontCollection应如下所示:

public void Dispose()
{
    foreach(FontImpl font in m_Implementation) {
        font.Dispose();
    }
    m_Implementation.Clear();
    m_Implementation = null;
}

清除只是从列表中删除所有内容。在本例中,您有一个IDisposable对象的列表,需要对列表中的所有项调用Dispose。打电话澄清并不能做到这一点

FontImpl应该实现IDisposable,因为它管理IDisposable对象:

 public void Dispose() {
      if (m_Font != null) {
          m_Font.Dispose();
          m_Font = null;
      }
 }
您的FontCollection应如下所示:

public void Dispose()
{
    foreach(FontImpl font in m_Implementation) {
        font.Dispose();
    }
    m_Implementation.Clear();
    m_Implementation = null;
}

在您所展示的代码中,您有实现IDisposable的字体对象,因此应该丢弃它们。这些对象由FontImpl类管理,因此FontImpl应该实现IDisposable。哟 Fontur FontCollection类包含FontImpl对象的列表,这些对象现在应该是一次性的,因此FontCollection需要实现IDisposable

您应该仔细阅读IDisposable模式,因此这个答案提供了一些很好的信息-


也就是说,从您提供的代码片段中,除了包装列表的类之外,您似乎没有从FontCollection中获得任何东西。除非你对这个类还有其他的事情要做,否则我将有一个列表作为成员变量。这样,在表单的Dispose方法中,您可以遍历列表并处理FontImpl对象。如果您想避免双重处理,那么在处理完所有内容后清空列表。

对于您显示的代码,您有实现IDisposable的字体对象,因此应该处理它们。这些对象由FontImpl类管理,因此FontImpl应该实现IDisposable。FontCollection类包含FontImpl对象的列表,这些对象现在应该是一次性的,因此FontCollection需要实现IDisposable

您应该仔细阅读IDisposable模式,因此这个答案提供了一些很好的信息-


也就是说,从您提供的代码片段中,除了包装列表的类之外,您似乎没有从FontCollection中获得任何东西。除非你对这个类还有其他的事情要做,否则我将有一个列表作为成员变量。这样,在表单的Dispose方法中,您可以遍历列表并处理FontImpl对象。如果你想避免重复处理,那么在处理完所有东西后清空列表。

请编辑你的答案,明确你应该只在不再使用的对象上处理它。是的,编辑它-这句话看起来很混乱,这是你需要关心的最重要的事情,但是是IDisposable对象。你真的需要对你实例化的每个实现IDisposable的对象调用Dispose。请编辑你的答案,明确你应该只在对象不再使用时才处理它。是的,编辑它-这句话看起来很混乱-你需要关心的最大的事情是IDisposable对象。您确实需要对每个实例化的实现IDisposable的对象调用Dispose。如何?它是可识别的。@JonathonReinhart嗯,是的,我不知道了。怎么样?它是可识别的。@JonathonReinhart嗯,是的,我不知道了。