Dispose()不会阻止内存不足异常

时间:2012-03-30 20:27:16

标签: c# dispose out-of-memory

我有一个巨大的日志文件,其中有大约1500万行。我必须将所有这些行移植到Oracle数据库。这就是我要做的事情:

  1. 我读取了DataTable的行(行以逗号分隔,以便 他们形成列)。我通过StreamReader阅读这些行并将其放入 使用它,以便在阅读完毕后摆脱它。
  2. 我把一个计数器在每行读取到DataTable时增加1。
  3. 当该计数器达到40.000时,我借助OracleBulkCopy将所有行导入数据库。
  4. 导入完成后我说:

    bulkCopier.Dispose();
    dataTable.Dispose();

  5. 然而,这对任何方式都无济于事。在任务管理器中,我看到内存使用量不断增长,直到内存不足为止。现在我的问题是Dispose()方法不会立即释放内存吗?如果是这样,那么为什么内存使用会累积,好像所有DataTable和OracleBulkCopy对象都保留内存一样。

3 个答案:

答案 0 :(得分:5)

Dispose不会立即释放托管内存。当您调用dispose时,Dispose将释放任何锁定到非托管资源(例如内存),并且与托管内存无关。

您的数据表全部填充了托管内存中的托管对象。打电话。对它进行处理不会做太多事情。你需要清除DataTable中的所有数据(有一个方便的Clear方法),这将允许垃圾收集器在将来某个时候释放内存,当它感觉像清理东西时起来。

使用分析器可以查看程序中所有内存的保存位置。很可能有许多其他托管对象要保留在引用中,这会阻止它们被垃圾回收。这与Dispose无关。

答案 1 :(得分:3)

不,处理信号将要拆除的内部句柄。具有Dispose的对象实际上会在以后获得GC-d。

如果这些是IDisposable,你应该尝试在using()块中使用它们,根据使用后自动发布的文档。

您可以使用GC.Collect强制GC集合,但我不认为这些对象是不同意的垃圾,.NET比那更好。

你能不能创建一个minidump并检查被卡住的内容以及为什么?

答案 2 :(得分:2)

  

现在我的问题是没有Dispose()方法释放内存   立即?

不一定。它将释放的唯一内存是由非托管资源分配的数量。它对托管堆没有影响。

您需要做的是确保没有对这些悬空DataTable实例的引用。您可能需要从集合中删除它们,或者根据需要null删除变量引用。