ValueType没有收集垃圾?

时间:2014-05-09 12:41:55

标签: c# collections garbage

 public struct LocalTLS : IDisposable
{
    public byte[] bArr;
    public string str;
    public LocalTLS(int k)
    {
        str = "Labamba";
        bArr = new byte[20000];
    }
    public void Dispose()
    {
        MessageBox.Show("In Dispose");
        //Thread.FreeNamedDataSlot("jaja");
        int k = 90;
        k += 90;
    }
} 
private void buttonTLS_retreive_Click(object sender, EventArgs e)
{
        LocalTLS lts = new LocalTLS(1);
}

点击事件返回后,我期待Dispose调用,但绝不会发生,有人可以解释一下。我不想做任何手动步骤,如调用Dispose或使用。我希望自动发生这种情况。

非常感谢您的所有答案,我想为LocalDataStoreSlot实现一个类,它将自动释放Slot并且超出范围,如注释代码所示。这将使开发人员免于记忆 call dispose,其中实际的FreeNamedDataSlot(...)发生。似乎这是不可能的

3 个答案:

答案 0 :(得分:1)

CLR不会一直执行垃圾收集,否则您的程序会因为执行GC而非常慢。要执行GC,CLR必须在回收超出范围对象使用的内存之前挂起所有线程。这是一个非常大的性能影响。

CLR将执行GC并在必要时调用对象的Dispose方法。除非有充分的理由,否则不要调用对象的Dispose()方法。如果对象与本机系统句柄,网络连接,文件句柄等相关联,那么这些是使用using关键字或调用它的Dispose()方法的充分理由。通常,CLR会使GC对象的范围超出范围,这样您的应用程序就不会耗尽内存。

我理解您的担忧,您认为byte [20000]对您的应用程序来说是一个重要的内存占用空间,并且您希望仔细控制内存使用情况。但这不是C ++。 CLR将自动为您管理内存。在我过去7年的.NET开发中,我只遇到过一个默认GC不够快的应用程序,我必须手动调用对象上的Dispose()。所以简而言之,只需将内存管理移交给CLR - 它做得非常好。

P.S。如果您对GC的内部工作感兴趣,可以在线阅读一些深入的文章。只需搜索 - 你就会找到它们。

答案 1 :(得分:0)

你要将对象声明包装在using中,如下所示:

using(LocalTLS lts = new LocalTLS(1))
{
   // use lts here

} // at this point, the Dispose method is called.

或手动调用Dispose方法:

lts.Dispose();

此外,垃圾收集器在代码中没有引用Dispose()时会自动调用lts方法。

答案 2 :(得分:0)

它是一个结构,它存在于内存堆栈而不是内存堆中。所以它不会像对象一样被车库收集器收集,因此GC不会调用dispose方法。当方法结束时,您的结构“LocalTLS”将被释放并从内存堆栈中取出。当它这样做时,它不会寻找IDisposable接口。