[英]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.