sql >> Base de Datos >  >> RDS >> Oracle

Fuga de memoria GetOracleDecimal

Este es un problema antiguo con ODP.NET (ver aquí:Problemas de memoria con ODP .NET 10.1.0.4 ).

El OracleDecimal type contiene una referencia a una instancia de una clase interna llamada OpoDecCtx . OpoDecCtx implementa IDisposable (ya que hace referencia a la memoria no administrada), pero dado que OracleDecimal no implementa IDisposable, tendrá que esperar a que se ejecute el recolector de elementos no utilizados para liberar la memoria no administrada subyacente. Puedes comprobar todo esto usando una herramienta como .NET Reflector.

Aunque técnicamente no se trata de una pérdida de memoria "física" (la memoria se liberará con el tiempo), en realidad es un problema cuando se trata de una gran cantidad de instancias del tipo OracleDecimal. No sé por qué Oracle no implementa simplemente IDisposable, es algo simple de hacer...

De todos modos, te sugiero que hagas un trabajo de pirateo tú mismo, usando la reflexión:

public static class OracleExtentions
{
    public static void Dispose(this OracleDecimal od) // build an extension method
    {
        if (OracleDecimalOpoDecCtx == null)
        {
            // cache the data
            // get the underlying internal field info
            OracleDecimalOpoDecCtx = typeof(OracleDecimal).GetField("m_opoDecCtx", BindingFlags.Instance | BindingFlags.NonPublic);
        }
        IDisposable disposable = OracleDecimalOpoDecCtx.GetValue(od) as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }

    private static FieldInfo OracleDecimalOpoDecCtx;
}

Y lo usarías así:

OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();