簡體   English   中英

在C#.NET中清理ODBC DSN

[英]Cleaning up ODBC DSN in C# .NET

我正在使用C#和OBDC DSN連接到Paradox數據庫。 如果打開和關閉每個連接,似乎正在泄漏內存。

我的代碼基本上是:

            csb.Dsn = "DNSName";
            OdbcConnection con = new OdbcConnection(csb.ConnectionString);
            con.Open();

            OdbcCommand comm= new OdbcCommand("SELECT * FROM Tabl", con);
            OdbcDataReader reader= null;
            try
            {
                reader= comm.ExecuteReader();
                for (int count = 0; (count < 5 && reader.Read()); ++count)
                {
                    //Read
                }
            }
            finally
            {
                if (reader!= null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                if (comm!= null)
                {
                    con.Close();
                    con.Dispose();
                    OdbcConnection.ReleaseObjectPool();
                    GC.Collect();
                    comm.Dispose();
                }
            }

有什么想法或建議嗎?

更新1

我將其更改為使用陳述,仍然泄漏。

using (var connection = new OdbcConnection(csb.ConnectionString))
{
    connection.Open();
    using (var command = new OdbcCommand("SELECT * FROM Tabl", connection))
    using (var reader =  command.ExecuteReader())
    {
        for (var count = 0; (count < 5 && reader.Read()); ++count)
        {
            //Read
        }
    }
}
OdbcConnection.ReleaseObjectPool();

上面的代碼中沒有內存泄漏,除非它是在“ // Read”執行點創建的。 GC.Collect永遠不會在生產中使用; 它很可能無論如何也無濟於事,實際上可能會因為自整定而阻礙GC。 抓取一個類似於ANTS Memory Profiler的探查器(或免費試用),查看掛在對象上的東西。

不要相信Windows任務管理器向您顯示是否泄漏 確保為此使用分析器。

嘗試將連接,命令和閱讀器放在using語句中。

然后調用OdbcConnection.ReleaseObjectPool(); 在末尾。

注意:運行垃圾收集可能需要幾分鍾的時間。 為了證明沒有泄漏,您可以連續調用三次GC.Collect() [三次清除所有三代中的對象]。

但是,請勿將GC.Collect()留在生產代碼中,因為它可能會嚴重影響性能。

您是如何發現泄漏的? 有時,由於GC不能立即啟動,或者由於您有連接池或尚未在托管環境中釋放的句柄,因此在任務管理器中內存使用率上升而不能立即釋放。 我建議您使用Travis建議的ANTS Mem Profiler之類的內存分析器。 您可以獲得試用版,否則可以使用Microsoft CLRProfiler的基本版本。

如果加載該過程,以便在分析過程中運行更長的時間,以便發現問題,這是另一個很好的措施。 最簡單的方法是在其周圍放一個循環,使上面的命令運行1000次或更多次。 您還可以使用性能監視器來監視某些感興趣的計數器,並查看它們在執行過程中的跟蹤方式。

盡量避免調用GC.Collect

除非您百分百確定自己知道自己在做什么,否則切勿觸摸垃圾收集器。 永遠記住-垃圾收集器比您聰明,並且知道最佳運行時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM