1

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

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 是否明智?

4

2 回答 2

2

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

于 2013-06-03T09:38:58.253 回答
1

如果将内存视为各种大小的仓库的集合,那么 .NET GC 循环在某种程度上相当于找到所有引用存在的对象,将位于一个特定仓库中的所有此类对象移动到不同的仓库,然后将搬出物品的仓库,并在旧仓库的场地上建造一个新的空仓库。一般来说,当一个小仓库装满时,在其中找到的物品会被移动到更大的仓库,直到它也被装满(然后那里的物品会被移动到更大的仓库)。

需要注意的重要一点是,即使系统通过某种方式知道其中一个仓库中不存在对某个特定对象的引用,该信息也不会很有帮助,因为系统通常不关心那些在仓库中,但不存在参考。按顺序分配仓库空间比尝试在这里和那里分配零碎的东西要快得多,也容易得多,而且炸毁和重建仓库同样快速和容易。

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

于 2013-06-03T20:44:02.127 回答