我需要一点帮助。
我现在在使用 Oracle.ManagedDataAccess.Core 时遇到问题。
我有一个为集中式 oracle 查询 (Clases.Oracle()
) 编写的类,它工作得很好,但是一个查询的内存使用量上升到 1GB,这不是一个真正的问题,考虑到结果集有大约 260.000最坏情况下的行。真正的问题是它永远不会释放该内存,如果我再次执行该查询,则会上升到 2GB,这是迄今为止的上限。
我尝试添加 GC.Collect()
和 GC.WaitForPendingFinalizers()
,但没有结果。
我在 Clases.Oracle()
中的命令执行函数是:
private DataTable ExecuteReader(string package, ref OracleParameter[] parametros, string owner)
{
var dt = new DataTable();
using (var cn = new OracleConnection(_connection_string))
{
using var cmd = cn.CreateCommand();
try
{
cn.Open();
cmd.CommandText = $"{owner}.{package}";
cmd.CommandType = CommandType.StoredProcedure;
foreach (var par in parametros)
{
cmd.Parameters.Add(par);
}
using var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
dt.Load(rdr);
}
catch (Exception ex)
{
throw new Exceptions.OracleException(ex.Message);
}
finally
{
cn?.Close();
cmd?.Dispose();
cn?.Dispose();
}
}
return dt;
}
我正在使用 using
子句,因此对象正在处理。
我正在使用这个函数调用连接:
public List<AuditoriaUsuarios> ObtieneAuditoriaUsuarios(long incluyeCargoRol = 0)
{
var ora = new Clases.Oracle();
var param = new OracleParameter[]
{
ora.AddInParameter("PIN_INCLUYECARGOROL",OracleDbType.Decimal, incluyeCargoRol),
ora.AddOutCursor("CUR_OUT"),
ora.AddOutParameter("PON_CODE", OracleDbType.Decimal),
ora.AddOutParameter("POV_ERROR", OracleDbType.Varchar2)
};
var result = ora.ExecuteReader<AuditoriaUsuarios>($"{_PCK}.p_AUDIT_USUARIOS", ref param);
if (ora.HayError(param))
{
throw new Exceptions.OracleException(ora.CodigoError, ora.MensajeError);
}
//GC.Collect();
//GC.WaitForPendingFinalizers();
return result;
}
Clases.Oracle()
不需要是 Disposable,因为我使用的所有对象都是 Disposable,并且正在被处理,以及 ConnectionString 和数据库所有者名称的 2 个字符串。
您可以在 ExecuteReader 完成并返回结果后很长时间内看到使用大量内存的 oracle 相关对象 (OracleInternal.Common.ZoneValue
)。
不知道是不是我做错了什么。
编辑:
我忘记了。这是一个 ASP .Net Core x64 WebAPI,使用 .NET Core 3.1 和 C#,以及 Visual Studio 2019 Enterprise。
编辑2:
我知道它很脏,但是将它添加到 ObtieneAuditoriaUsuarios
会使情况好一些。 (在这种情况下我不关心 CPU 使用率,因为这个数据提取它应该每周执行几次,而不是日常操作的一部分):
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
编辑3: 我同时发送了 8 个请求,在某些测试中内存使用量上升到 3GB。但是只需要 1 个请求,过滤器返回少于 100 行,内存使用量下降到小于 1GB