应该使用大量内存的类实现System.IDisposable

时间:2013-06-03 09:32:09

标签: memory-management garbage-collection

假设我创建了一个类,它导致对象使用大量内存,但没有非托管资源:

class TestMemory
{
    public int[] intarray = new int[1000000];
}

通常,如果我创建了这个类的对象,并在使用后丢弃对该对象的所有引用,那么垃圾收集器最终将负责释放内存。

问题在于垃圾收集器何时会这样做是不确定的。它可能需要几秒钟,甚至可能需要几分钟才能使垃圾收集器释放内存

假设我想经常重新创建这个对象,例如像这样(我知道,有效率):

for (int i=0; i < 1E10; ++i)
{
    List<TestMemory> myList = new List<TestMemory>();
    for (int j=0; j < 400; ++j)
    {
         myList.Add(new TestMemory());
    }
}

我是否应该担心内存不足,或者当请求的内存超过当前可用内存时,垃圾收集器是否会额外收集?为这个托管代码实现IDisposable是明智的吗?

2 个答案:

答案 0 :(得分:2)

IDisposable适用于拥有非托管资源的类(文件句柄,SQL事务,本机库的分配)。

答案 1 :(得分:1)

如果将内存视为各种大小的仓库集合,则.NET GC循环在某种程度上等同于查找存在引用的所有对象,将位于特定仓库中的所有此类对象移动到不同的仓库,炸毁移动物体的仓库,并在旧仓库的旧址上建立一个新的空仓库。一般来说,当一个小仓库变满时,在它们中找到的对象将被移动到一个较大的仓库,直到它变满为止(此时那里的对象将被移动到更大的对象)。

需要注意的一点是,即使系统知道某个仓库中的某个特定对象不存在任何参考,该信息也不会很有用,因为系统通常不关心关于仓库中但没有参考的东西。按顺序分配仓库空间要比在这里和那里分配一点点零碎更快更容易,而且仓库的动态和重建也同样快捷方便。

在放弃对数组本身的最后一次引用之前,有些情况下使用大类数组类型的代码可能会从数组中清除所有引用中受益(特别是如果数组本身很老的话) ,但包含对大多数新对象的引用)。但是,一般来说,应该认为系统在需要回收内存时会执行GC循环,并且不会从内存可以更快地回收的知识中获益。