Dispose()不会阻止内存不足异常
本文关键字:内存不足 异常 Dispose | 更新日期: 2023-09-27 18:29:44
我有一个巨大的日志文件,其中大约有1500万行。我必须将所有这些行移植到Oracle数据库。以下是我要做的:
- 我读取DataTable中的行(行用逗号分隔,以便它们形成列)。我通过StreamReader阅读了这些行,并将其放入使用,以便在完成阅读后将其清除
- 我在DataTable中放入了一个计数器,每读取一行,计数器就会增加1
- 当计数器达到40.000时,我在OracleBulkCopy的帮助下将所有行导入数据库
-
当导入完成时,我说:
bulkCopier.Dispose();
dataTable.Dispose();
然而,这对任何方式都没有帮助。在任务管理器中,我看到内存使用量在增长,直到内存不足。现在我的问题是Dispose()
方法不会立即释放内存吗?如果是这样,那么为什么内存使用量会累积,就好像所有DataTable和OracleBulkCopy对象都在保留内存一样。
Dispose不会立即释放托管内存。当您调用Dispose时,Dispose会释放对非托管资源(如内存)的任何锁,并且与托管内存无关。
您的数据表全部由托管内存中的托管对象填充。调用。处理它不会有多大作用。您需要从DataTable中清除所有数据(有一种方便的Clear
方法可以做到这一点),这将允许垃圾收集器在未来某个时间点释放内存,因为它感觉像是在清理东西。
使用探查器,您可以查看程序中所有内存的确切存放位置。很可能还有许多其他托管对象被您持有引用,这防止了它们被垃圾收集。这与Dispose
无关。
不,dispose发出内部句柄被拆除的信号。具有Dispose的对象实际上稍后会得到GC-d。
根据使用后自动发布的文档,如果这些IDisposable,您应该尝试在using()块中使用它们。
你可以用GC.Collect强制GC收集,但我不认为那些对象是未解冻的grabage,.NET比这更好。
你能不创建一个小型转储并检查什么东西被卡住了吗?为什么?
现在我的问题是Dispose()方法是否释放内存立即
不一定。它将释放的唯一内存是非托管资源分配的内存量。它对托管堆没有任何影响。
您需要做的是确保没有引用这些悬空的DataTable
实例。您可能需要从集合中删除它们,或者根据需要从变量引用中删除null
。