Garbage Collector C#, question about 'clearing' objects
我阅读了一些有关垃圾收集的信息(它的工作方式等)。 我尝试了解示例的工作方式,但我认为有问题。 我知道垃圾收集器在以下情况下运行:
内存不足,
您调用GC.Collect()。
这是我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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时,我正在创建新的对象Testing。 _d是对此新对象的引用。 我正在使用JetBrains dotTrace Memory转储内存,并看到此新对象存在。 单击button2之后,我将布尔值_first设置为true,以使_d变得不可访问。 在这一点上,我认为当我运行GC.Collect()时,GC会从堆栈中"清除"该对象,但我发现它仍然存在。 我对GC工作误解了吗? 还是我做错了吗?
当我设置
单击Button2不会使
GC仅收集没有被根对象引用的对象。
只要您的表单引用了
设置
如果有人再次设置
这是因为
无法访问并不意味着不能将
因此,GC无法清除它,因为它可能在以后的代码中仍在使用。
您误解了GC如何确定可访问对象:当前局部范围内的变量引用的任何对象,可访问对象的任何静态变量和任何实例变量本身都是"可访问的"-将其视为具有上述变量作为图的"根"的图。
在您的示例中,
如果要调用GC.Collect(),则将考虑所有对象(无论它们在内存中已经存放了多长时间);但是,GC不会收集托管代码中引用的对象。检查一下