Dit is een oud probleem met ODP.NET (zie hier:Geheugenproblemen met ODP .NET 10.1.0.4 ).
De OracleDecimal
type bevat een verwijzing naar een instantie van een interne klasse met de naam OpoDecCtx
. OpoDecCtx implementeert IDisposable
(omdat het zelf verwijst naar onbeheerd geheugen), maar aangezien OracleDecimal IDisposable niet implementeert, moet u wachten tot de garbage collector is gestart om het onderliggende onbeheerde geheugen vrij te maken. U kunt dit allemaal controleren met een tool zoals .NET Reflector.
Hoewel het technisch gezien geen "fysiek" geheugenlek is (geheugen zal uiteindelijk worden vrijgemaakt), is het eigenlijk een probleem wanneer je te maken hebt met een groot aantal instanties van het OracleDecimal-type. Ik weet niet waarom Oracle IDisposable niet gewoon implementeert, het is heel eenvoudig om te doen...
Hoe dan ook, ik stel voor dat je zelf wat hackwerk doet, met behulp van reflectie:
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;
}
En je zou het als volgt gebruiken:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();