abh*_*vce 1 .net c# garbage-collection
我是用的垃圾收集器实验和发现了奇怪的计数iCnt的destructor电话.这是守则: -
public class MyClass
{
static long iCnt;
public MyClass()
{
iCnt++;
}
~MyClass()
{
iCnt--;
}
static public string ObjectCount
{
get
{
return iCnt.ToString();
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面的代码是创建对象,删除对象(通过分配去参考null)和显式调用GC.Collect().我已经让所有它具有运表Timer中interval = 100,计时器显示的当前计数iCnt.
public partial class Form1 : Form
{
MyClass[] Objs;
public Form1()
{
InitializeComponent();
}
private void btnCreateObjects_Click(object sender, EventArgs e)
{
Objs = new MyClass[1000];
for (int i = 0; i < 1000; i++)
{
Objs[i] = new MyClass();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = MyClass.ObjectCount;
}
private void btnDeleteObjects_Click(object sender, EventArgs e)
{
for (int i = 0; i < 1000; i++)
{
Objs[i] = null;
}
}
private void btnInvokeGC_Click(object sender, EventArgs e)
{
GC.Collect();
}
}
Run Code Online (Sandbox Code Playgroud)
现在创建对象,直到自动调用垃圾收集器(对我来说,它需要24次点击).再次重复此动作.
我看到这iCnt<1000.这让我混淆了析构函数在这种情况下如何调用.当iCnt<1000时,点击删除对象的删除对象Objs[1000].然后调用GC.Collect()计数iCnt<0(非常奇怪).
任何人都可以解释我这种行为.提前致谢.
这是一个非常经典的线程错误.析构函数在终结器线程上运行,与递增计数的线程异步.您需要使用Interlocked.Increment()和Decrement()来安全地执行此操作.或者使用lock关键字.