Ini adalah masalah lama dengan ODP.NET (lihat di sini:Masalah Memori dengan ODP .NET 10.1.0.4 ).
OracleDecimal
type menyimpan referensi ke instance kelas internal bernama OpoDecCtx
. OpoDecCtx mengimplementasikan IDisposable
(karena itu sendiri mereferensikan memori yang tidak dikelola), tetapi karena OracleDecimal tidak mengimplementasikan IDisposable, Anda harus menunggu pengumpul sampah berjalan untuk membebaskan memori tidak terkelola yang mendasarinya. Anda dapat memeriksa semua ini menggunakan alat seperti .NET Reflector.
Meskipun secara teknis ini bukan kebocoran memori "fisik" (memori pada akhirnya akan dibebaskan), sebenarnya ini adalah masalah ketika Anda berurusan dengan sejumlah besar instance dari tipe OracleDecimal. Saya tidak tahu mengapa Oracle tidak hanya mengimplementasikan IDisposable, ini adalah hal yang sederhana untuk dilakukan...
Bagaimanapun, saya sarankan Anda melakukan pekerjaan hack sendiri, menggunakan refleksi:
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;
}
Dan Anda akan menggunakannya seperti ini:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();