我正在使用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;
}
答案 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。