Утечка памяти с OracleCommand - PullRequest
       5

Утечка памяти с OracleCommand

2 голосов
/ 19 февраля 2009

Я использую ODP.Net версии 11.1.0 для вставки данных в базу данных и наблюдаю утечку памяти. Если я закомментирую код ниже, он исчезнет. Этот код вызывается тысячи раз в моем приложении, и я могу наблюдать, как количество байт во всех кучах постоянно увеличивается по мере его запуска. cmdStr содержит оператор вставки, который вставляет в таблицу с 375 столбцами. Поля все НОМЕР, кроме двух - одно - ДАТА, а другое - VARCHAR2 (20). Есть ли что-то еще, что мне нужно сделать, чтобы очистить 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;
}

Ответы [ 6 ]

4 голосов
/ 21 февраля 2009

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

try
{
    using (OracleConnection conn = new OracleConnection(connectionString))
    {
        using (OracleCommand cmd = new OracleCommand(cmdStr, conn))
        {
        ....
        }
    }
}
catch (OracleException e)
{
  ....
}

Это позволит избавиться от объекта OracleConnection как можно скорее, даже если исключение OracleException произойдет внутри операторов using.

1 голос
/ 21 февраля 2009

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

1 голос
/ 19 февраля 2009

Попробуйте реструктурировать его так:

  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
0 голосов
/ 21 февраля 2017

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

0 голосов
/ 21 февраля 2009

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

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

0 голосов
/ 19 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...