7

我有一些对象可以读取文件,将数据保存在数组中并进行一些操作。顺序是创建对象A,对对象A进行操作。创建对象B,对对象B进行操作……每个对象读取的数据可能在10MB左右。所以最好的选择是在对每个对象进行操作后删除每个对象。假设我希望我的程序分配大约 10 MB 的内存,而不是 10MB * 1000 个对象 = 1GB

对象类似于:

class MyClass
{  
    List<string[]> data;

    public MyClass(string datafile)
    {
        using (CsvReader csv = new CsvReader(new StreamReader(datafile), true))
        {
            data = csv.ToList<string[]>();
        }
    }

    public List<string> Operate()
    {
    ...
    }

}

我的问题是:我应该实施处置吗?并执行以下操作:

List<string> results = new List<results>();

using (MyClass m = new MyClass("fileM.txt"))
            {
                results.AddRange(m.Operate());
            }

using (MyClass d = new MyClass("fileD.txt"))
            {
                results.AddRange(d.Operate());
            }

...

我已经读过,当您使用非托管资源(套接字、流等)时,建议实施 Disposable,但在我的班级中,我只有大数据数组。

另一种方法是为每个对象创建函数(我想 GC 会自动删除在函数中创建的对象):

List<string> results = new List<results>();
results.AddRange(myFunction("fileM.txt"));
results.AddRange(myFunction("fileD.txt"));


public List<string> myFunction(string file)
{
MyClass c = new MyClass(file);
return results.AddRange(c.Operate());
}
4

3 回答 3

5

IDisposable等在这​​里不会帮助你,因为它不会导致任何东西被收集。在这种情况下,也许最好的方法是使用来减少分配 - 本质上成为您自己的内存管理器。例如,如果您List<string>很大,您可以通过重新使用列表来避免很多数组 - 显然,在清除它们之后。如果您调用.Clear(),则不会重置支持数组 - 它只是设置一个逻辑标记以将其视为空。在您的特定情况下,您的许多对象将是个人string;这比较棘手,但至少它们很小,应该可以在零代收集。

于 2013-02-22T02:04:21.267 回答
3

在你的情况下,我会分配一个缓冲区数组。例如,一次分配一个 10 MB 的数组,然后用您想要的数据填充它。然后,当您到达下一个对象时,只需重用该数组。如果您需要更大的数组,您可以分配一个新的更大的数组并使用它。垃圾收集器最终会移除您较小的垃圾收集器。

你也可以使用 a List<T>,它会在内部做同样的事情(分配一个数组,保持它直到它变得太小,分配一个新的)。就Clear在创建下一个对象之前。

请注意,您不能强制1垃圾收集器收集对象。IDisposable确实仅用于清理非托管资源,因为垃圾收集器不知道它们,或者关闭(文件)句柄。调用Dispose不保证(或暗示)对象已从内存中删除。

但是,如果您什么都不做,您的代码仍然是正确的并且可以正常工作。垃圾收集器负责在需要时删除未使用的对象,并确保始终有足够的内存可用。要让收集器完成其工作,您唯一要做的就是放弃对旧对象的任何引用(通过覆盖它们或将它们设置为null,或让它们超出范围)。

1)您可以通过调用强制垃圾收集器收集您的数据GC.Collect()。但是,建议这样做。让垃圾收集器自己解决。

于 2013-02-22T02:05:17.247 回答
0

如果您使用的是 .NET 4.0 或更高版本,请查看BlockingCollection类。采用 Int32 参数的构造函数允许您指定集合大小的上限。Add和Take方法用作节流阀仅当未达到上限时,添加才会成功。如果有,它会阻塞。仅当项目存在时才会成功。如果不存在任何项目,它将阻塞,直到有一个可用。当然,该类具有这些方法的一些变体,因此请全面检查文档以查看哪些(如果有)有意义。

于 2013-02-22T02:28:20.960 回答