垃圾收集器C#,有关“清除”对象的问题

问题描述

|| 我阅读了有关垃圾收集的一些信息(它的工作方式等)。我试图了解示例的工作方式,但是我认为我有问题。我知道垃圾收集器在以下情况下运行: 内存不足, 您调用GC.Collect()。 这是我的代码
public partial class Form1 : Form
{
    public Testing _d;
    public Boolean _first = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender,EventArgs e)
    {
        if (!_first)
        {
            _d = new Testing();
            int test = _d.DoSomething(\"example\");
        }
    }

    private void button2_Click(object sender,EventArgs e)
    {
        _first = true;
    }

    private void button3_Click(object sender,EventArgs e)
    {
        //if (_first)
        //{
        //    _d = null;
        //}
        GC.Collect();
    }
}

public class Testing
{
    private ASCIIEncoding _ascii;
    private bool _disposed = false;

    public Testing()
    {
        _ascii = new ASCIIEncoding();
    }

    public int DoSomething(string message)
    {
        return _ascii.GetByteCount(message);
    }
}
单击button1时,我正在创建新的对象“测试”。 _d是对此新对象的引用。我正在使用JetBrains dottrace Memory转储内存,并看到此新对象存在。单击button2之后,我将布尔值_first设置为true,以使_d变得不可访问。在这一点上,我认为当我运行GC.Collect()时,GC会从堆栈中“清除”该对象,但我仍然看到它仍然存在。我对GC工作误解了吗?还是我做错了吗? 设置set1ѭ就可以了     

解决方法

        就GC而言,设置
first=false
不会使
_d
实例不可访问。从逻辑上讲,您可能永远不会再使用它,但仍在
Form1
类中引用了它。 如果有人再次设置
first=true
,您是否不希望该对象仍然可用?     ,        单击Button2不会使“ 3”无法访问。 GC仅收集没有被根对象引用的对象。 只要您的表格中引用了
_d
,就不会收集该表格。     ,        这是因为“ 3”是对您设置且永不清除的“ 9”实例的引用。
_d
仍指向堆上的对象,并且将维持此引用,直到您清除它为止(通过调用(
_d = null
)。 不可达并不意味着不能将ѭ3分配给其他对象,而是堆中的对象没有机会再次被调用(因为代码中不存在引用) 因此,GC无法清除它,因为它可能在以后的代码中仍在使用。     ,        您误解了GC如何确定可访问对象:当前本地范围中的变量引用的任何对象,可访问对象的任何静态变量和任何实例变量本身都是“可访问”-它作为图,其中前面提到的变量为图的“根”。 在您的示例中,“ 3”仍然保留着对您对象的引用,因此它仍然可以访问并且不会被垃圾回收。     ,        如果要调用GC.Collect(),则将考虑所有对象(无论它们在内存中已经存放了多长时间);但是,GC不会收集托管代码中引用的对象。检查一下