OracleCommand导致内存泄漏

时间:2009-02-19 14:59:00

标签: .net oracle

我正在使用ODP.Net版本11.1.0将数据插入数据库,我看到内存泄漏。如果我注释掉下面的代码,它就会消失。这个代码在我的应用程序中被调用了数千次,我可以看到所有堆中的字节数在运行时稳定增长。 cmdStr包含一个插入语句,该语句插入到包含375列的表中。除了两个字段外,这些字段都是NUMBER - 一个是DATE,另一个是VARCHAR2(20)。我还需要做些什么来清理OracleCommand吗?这里不会抛出任何异常 - 每次insert命令都成功。

编辑:我尝试移动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 个答案:

答案 0 :(得分:4)

尝试使用围绕using语句的OracleConnection包装using语句,如下所示:

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

这将尽快摆脱OracleConnection对象 - 即使在using语句中发生OracleException也是如此。

答案 1 :(得分: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

答案 2 :(得分:1)

你保持连接打开吗?每次需要发出此命令时尝试打开一个新连接(无论如何都要汇总它,这样不会影响性能),关闭&在完成事务后处理它并查看内存泄漏是否消失。

答案 3 :(得分:0)

尝试将return语句移到using块之外。

答案 4 :(得分:0)

连接池上的最大连接数是多少?默认情况下,连接池启用100个最大连接。

您不会显示创建/部署连接的代码部分。我怀疑更有可能找到问题的地方。

答案 5 :(得分:0)

尝试使用:Oracle.ManagedDataAccess.Client而不是Oracle.DataAccess.Client。