sql >> Databasteknik >  >> RDS >> Oracle

GetOracleDecimal Minnesläcka

Detta är ett gammalt problem med ODP.NET (se här:Minnesproblem med ODP .NET 10.1.0.4 ).

OracleDecimal typ innehåller en referens till en instans av en intern klass med namnet OpoDecCtx . OpoDecCtx implementerar IDisposable (eftersom det i sig refererar till ohanterat minne), men eftersom OracleDecimal inte implementerar IDisposable, måste du vänta på att sopsamlaren kör för att frigöra det underliggande ohanterade minnet. Du kan kontrollera allt detta med hjälp av ett verktyg som .NET Reflector.

Även om det tekniskt sett inte är en "fysisk" minnesläcka (minnet kommer så småningom att frigöras) är det faktiskt ett problem när du har att göra med en stor mängd instanser av typen OracleDecimal. Jag vet inte varför Oracle inte bara implementerar IDisposable, det är en enkel sak att göra...

Hur som helst, jag föreslår att du gör något hackjobb själv med hjälp av reflektion:

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

Och du skulle använda det så här:

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


  1. Rita flera polygoner på Google Maps API v3 från MySQL-databas

  2. Hämta id för varje INSERT-sats i flera frågor

  3. Kopiera tabelldata från en DB till en annan

  4. Lagra filsökvägar i en databas