Това е стар проблем с ODP.NET (вижте тук:Проблеми с паметта с ODP .NET 10.1.0.4 ).
OracleDecimal
тип съдържа препратка към екземпляр на вътрешен клас с име OpoDecCtx
. OpoDecCtx имплементира IDisposable
(тъй като самият той препраща към неуправлявана памет), но тъй като OracleDecimal не прилага IDisposable, ще трябва да изчакате събирачът на боклук да стартира, за да освободи основната неуправляема памет. Можете да проверите всичко това с помощта на инструмент като .NET Reflector.
Въпреки че технически не е "физическо" изтичане на памет (паметта в крайна сметка ще бъде освободена), това всъщност е проблем, когато имате работа с голямо количество екземпляри от типа OracleDecimal. Не знам защо Oracle просто не имплементира IDisposable, това е просто нещо за правене...
Както и да е, предлагам ви сами да извършите хакерска работа, като използвате отражение:
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;
}
И бихте го използвали така:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();