DbDataReader导致OutOfMemoryException

时间:2018-02-21 22:41:45

标签: .net memory memory-leaks out-of-memory dbdatareader

我正在使用DbDataReader(OracleDataReader)类从Oracle数据库中读取数据。我在Visual Studio 2010中运行程序,使用64位Windows 10企业版笔记本电脑,32GB RAM(20GB免费),使用.NET 3.5(升级到较新的.NET版本不是一个选项。应用程序本身是一个32位应用程序(不是选择)。

代码看起来像这样:

//...some code to setup database connection, command, etc.
DbDataReader reader = null;
int count = 0;

try {
    reader = command.ExecuteReader();
    if(reader.HasRows) {
        while(reader.Read()) {
            count++;
        }
    }
}
finally {
    if(reader != null) { reader.Close(); }
}

堆栈追踪:

System.OutOfMemoryException was unhandled
    Message=Exception of type 'System.OutOfMemoryException' was thrown.
    Source=Oracle.DataAccess
    StackTrace:
    at Oracle.DataAccess.Client.OracleDataReader.Dispose(Boolean disposing)
    at Oracle.DataAccess.Client.OracleDataReader.Close()
    at Test.Program.Main(String[] args)
    at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()

我也多次使用此堆栈跟踪:

System.OutOfMemoryException was caught
    Message=Exception of type 'System.OutOfMemoryException' was thrown.
    Source=Oracle.DataAccess
    StackTrace:
        at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
        at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src, Boolean bCheck)
        at Oracle.DataAccess.Client.OracleDataReader.Read()
        at Test.Program.Main(String[] args)

我不是在这个测试用例中自己分配任何内存,我只是递增一个整数,但我仍然没有内存,这告诉我DbDataReader正在分配内存并且可能没有正确地释放它(或者及时)。我已经尝试手动进行垃圾收集,看看是否有帮助,但事实并非如此。我还调查了它崩溃的行是否包含太多数据,从而填满了剩余的内存,但这并没有加起来,因为从其他行读取了大量的数据(并被丢弃)在崩溃之前。

非常感谢任何想法/帮助,谢谢!

1 个答案:

答案 0 :(得分:2)

在使用OracleCommand和OracleDataReader上的各种设置修补了一下之后,问题变成了最初在OracleDataReader上的FetchSize太高了。

执行命令后在OracleDataReader上设置FetchSize可以解决问题并允许应用程序在没有任何内存错误的情况下运行。