DbDataReader вызывает OutOfMemoryException
Я читаю данные из базы данных Oracle, используя класс DbDataReader (OracleDataReader). Я запускаю программу в Visual Studio 2010 с 64-разрядным ноутбуком Windows 10 Enterprise с 32 ГБ ОЗУ (20 ГБ свободно), использую.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 ответ
Немного повозившись с различными настройками в OracleCommand и OracleDataReader, проблема оказалась в том, что FetchSize изначально был слишком высок в OracleDataReader.
Установка FetchSize в OracleDataReader после выполнения команды решает проблему и позволяет приложению работать без ошибок памяти.