Este é um problema antigo com o ODP.NET (veja aqui:Problemas de memória com ODP .NET 10.1.0.4 ).
O
OracleDecimal
type contém uma referência a uma instância de uma classe interna chamada OpoDecCtx
. OpoDecCtx implementa IDisposable
(como ele próprio faz referência à memória não gerenciada), mas como o OracleDecimal não implementa IDisposable, você terá que esperar que o coletor de lixo seja executado para liberar a memória não gerenciada subjacente. Você pode verificar tudo isso usando uma ferramenta como o .NET Reflector. Embora não seja tecnicamente um vazamento de memória "física" (a memória será eventualmente liberada), na verdade é um problema quando você está lidando com uma grande quantidade de instâncias do tipo OracleDecimal. Não sei porque a Oracle não implementa simplesmente IDisposable, é uma coisa simples de fazer...
De qualquer forma, sugiro que você faça algum trabalho de hack, usando reflexão:
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 você usaria assim:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();