これはODP.NETの古い問題です(ここを参照:ODPのメモリの問題.NET 10.1.0.4 。
OracleDecimal
typeは、OpoDecCtx
という名前の内部クラスのインスタンスへの参照を保持します 。 OpoDecCtxはIDisposable
を実装します (それ自体がアンマネージメモリを参照しているため)が、OracleDecimalはIDisposableを実装していないため、ガベージコレクタが実行されて基になるアンマネージメモリが解放されるのを待つ必要があります。 .NETReflectorなどのツールを使用してこれらすべてを確認できます。
技術的には「物理的な」メモリリークではありませんが(メモリは最終的に解放されます)、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();