2009-02-19 3 views
2

Я использую ODP.Net версии 11.1.0 для вставки данных в базу данных, и я вижу утечку памяти. Если я прокомментирую приведенный ниже код, он исчезнет. Этот код называется тысячами раз в моем приложении, и я могу наблюдать за количеством байтов во всех кучах, которые постоянно растут. cmdStr содержит инструкцию insert, которая вставляет в таблицу с 375 столбцами. Поля - всего NUMBER, за исключением двух - один - ДАТА, а другой - VARCHAR2 (20). Есть ли что-то еще, что мне нужно сделать, чтобы очистить OracleCommand? Здесь нет исключений - команда вставки успешно выполняется каждый раз.Утечка памяти с OracleCommand

Редактировать: Я попытался переместить оператор return, и это не имело никакого эффекта, как ожидалось, - это действительно блок try-finally.

Обновление: Я использовал CLRProfiler, чтобы узнать, что использует память, и это куча строковых объектов, из которых 2800. Их ссылки хранятся объектами HashTable, принадлежащими объектам Oracle.DataAccess.Client.ConnDataPool. Почему ODP.NET поддерживает их?

try 
{ 
    using (OracleCommand cmd = new OracleCommand(cmdStr, conn)) 
    { 
     cmd.CommandTimeout = txTimeout; 
     int nRowsAffected = cmd.ExecuteNonQuery(); 
     errMsg = null; 
     return EndpointResult.Success; 
    } 
} 
catch (OracleException e) 
{ 
    return BFOracleAdapter.HandleOracleException(e, out errMsg); 
} 
catch (Exception e) 
{ 
    errMsg = "OracleInsertOperation Exception: " + e.Message; 
    return EndpointResult.Error; 
} 
+0

Все выглядит хорошо в этом коде. Вопросы: 1. Правильно ли вы используете объект OracleConnection? 2. Что находится в строках, которые вы видите в CLRProfiler? Как взломать, я думаю, что есть способ закрыть/сбросить все соединения в пуле соединений ... – ConsultUtah

ответ

0

Попробуйте переместить оператор return за пределы используемого блока.

+0

Использование будет очищать, однако вы выходите из него. Вероятно, проблема заключается в том, что «conn» не используется. – Loofer

1

Постарайся перестраивает ее на что-то вроде:

object o; 
    using (OracleCommand cmd = new OracleCommand(cmdStr, conn)) 
    { 
    try 
    { 
     cmd.CommandTimeout = txTimeout; 
     int nRowsAffected = cmd.ExecuteNonQuery(); 
     errMsg = null; 
     o = EndpointResult.Success; 
    } 
    catch (OracleException e) 
    { 
     o = BFOracleAdapter.HandleOracleException(e, out errMsg); 
    } 
    catch (Exception e) 
    { 
     errMsg = "OracleInsertOperation Exception: " + e.Message; 
     o = EndpointResult.Error; 
    } 
    finally 
    { 
     // clean up 
    } 
    } 
    return o 
1

ли вы держите соединение открытым? Попробуйте открыть новое соединение каждый раз, когда вам нужно выпустить эту команду (она все равно объединена, так что это не повлияет на производительность), закройте & после того, как вы закончите транзакцию, и посмотрите, не пропадет ли утечка памяти.

4

Попробуйте обертывание с использованием заявление с OracleConnection вокруг с помощью заявления, как это:

Это избавится от объекта OracleConnection как можно скорее - даже тогда, когда OracleException будет больше появляться внутри с помощью утверждений ,

0

Какое максимальное количество подключений в вашем пуле подключений? По умолчанию пул соединений включен с 100 максимальными соединениями.

Вы не видите часть кода, который создает/удаляет соединения. Я подозреваю, что более вероятно, где проблема будет найдена.

0

Попробуйте использовать: Oracle.ManagedDataAccess.Client вместо Oracle.DataAccess.Client.

Смежные вопросы