Oracle
 sql >> Database >  >> RDS >> Oracle

GetOracleDecimal Perdita di memoria

Questo è un vecchio problema con ODP.NET (vedi qui:Problemi di memoria con ODP .NET 10.1.0.4 ).

Il OracleDecimal type contiene un riferimento a un'istanza di una classe interna denominata OpoDecCtx . OpoDecCtx implementa IDisposable (poiché esso stesso fa riferimento alla memoria non gestita), ma poiché OracleDecimal non implementa IDisposable, dovrai attendere l'esecuzione del Garbage Collector per liberare la memoria non gestita sottostante. Puoi controllare tutto questo usando uno strumento come .NET Reflector.

Sebbene non sia tecnicamente una perdita di memoria "fisica" (la memoria verrà eventualmente liberata), in realtà è un problema quando si ha a che fare con una grande quantità di istanze del tipo OracleDecimal. Non so perché Oracle non implementa semplicemente IDisposable, è una cosa semplice da fare...

Ad ogni modo, ti suggerisco di fare un po' di hack da solo, usando la riflessione:

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;
}

E lo useresti così:

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