我正在使用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正在分配内存并且可能没有正确地释放它(或者及时)。我已经尝试手动进行垃圾收集,看看是否有帮助,但事实并非如此。我还调查了它崩溃的行是否包含太多数据,从而填满了剩余的内存,但这并没有加起来,因为从其他行读取了大量的数据(并被丢弃)在崩溃之前。
非常感谢任何想法/帮助,谢谢!
答案 0 :(得分:2)
在使用OracleCommand和OracleDataReader上的各种设置修补了一下之后,问题变成了最初在OracleDataReader上的FetchSize太高了。
执行命令后在OracleDataReader上设置FetchSize可以解决问题并允许应用程序在没有任何内存错误的情况下运行。