Đây là sự cố cũ với ODP.NET (xem tại đây: Sự cố bộ nhớ với ODP .NET 10.1.0.4 ).
OracleDecimal
kiểu giữ một tham chiếu đến một phiên bản của lớp nội bộ có tên là OpoDecCtx
. OpoDecCtx triển khai IDisposable
(vì bản thân nó tham chiếu đến bộ nhớ không được quản lý), nhưng vì OracleDecimal không triển khai IDisposable, bạn sẽ phải đợi bộ thu gom rác chạy để giải phóng bộ nhớ không được quản lý bên dưới. Bạn có thể kiểm tra tất cả những điều này bằng một công cụ như .NET Reflector.
Mặc dù về mặt kỹ thuật, nó không phải là một rò rỉ bộ nhớ "vật lý" (bộ nhớ cuối cùng sẽ được giải phóng), nhưng nó thực sự là một vấn đề khi bạn đang xử lý một lượng lớn các phiên bản của kiểu OracleDecimal. Tôi không biết tại sao Oracle không triển khai IDisposable một cách đơn giản, đó là một việc đơn giản để làm ...
Dù sao, tôi khuyên bạn nên tự mình thực hiện một số công việc hack, sử dụng phản chiếu:
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;
}
Và bạn sẽ sử dụng nó như thế này:
OracleDecimal od = reader.GetOracleDecimal(5);
decimal volume = (decimal)OracleDecimal.SetPrecision(od, 28);
od.Dispose();