To stary problem z ODP.NET (zobacz tutaj:Problemy z pamięcią z ODP .NET 10.1.0.4 ).
OracleDecimal
type zawiera referencję do instancji klasy wewnętrznej o nazwie OpoDecCtx
. OpoDecCtx implementuje IDisposable
(ponieważ sam odwołuje się do pamięci niezarządzanej), ale ponieważ OracleDecimal nie implementuje IDisposable, musisz poczekać na uruchomienie modułu wyrzucania elementów bezużytecznych, aby zwolnić podstawową pamięć niezarządzaną. Możesz to wszystko sprawdzić za pomocą narzędzia takiego jak .NET Reflector.
Chociaż technicznie nie jest to „fizyczny” wyciek pamięci (pamięć zostanie ostatecznie zwolniona), w rzeczywistości jest to problem, gdy mamy do czynienia z dużą liczbą wystąpień typu OracleDecimal. Nie wiem, dlaczego Oracle nie implementuje po prostu IDisposable, to prosta rzecz do zrobienia...
W każdym razie sugeruję, abyś sam wykonał trochę pracy hakerskiej, używając refleksji:
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;
}
Używałbyś go tak:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();