2011-03-05 44 views
2

在我的應用程序中,我使用ADODB來查詢MySQL數據庫。這很順利,但是,ADODB似乎泄漏了很多內存。C#泄漏內存中的ADODB

我通過調用每個執行的查詢的close方法來部分修復它。
我發現用這種方法標杆百萬查詢:

public static int Execute(string query) 
{ 
    Connect(); 
    object ret; 
    lock (_conn) 
     _conn.Execute(query, out ret, -1); 
    return (int)ret; 
} 

一個約10000查詢我出的內存後,速度極快。

我想這是因爲_conn.Execute的,所以我把它改爲:

public static int Execute(string query) 
{ 
    Connect(); 
    object ret; 
    ADODB.Recordset rs; 
    lock (_conn) 
     rs = _conn.Execute(query, out ret, -1); 
    rs.Close(); 
    return (int)ret; 
} 

現在,這似乎節省了很多,但在執行查詢100000後,繼續泄漏左右的內存爲80MB。

有誰知道如何阻止它泄漏內存,我不需要記錄集。我有3個不同的函數,一個用於像這樣執行,一個用於執行和返回包裝在我自己的類中的記錄集,另一個用於執行並返回最後插入的ID,這對INSERT INTO查詢很有用。

那麼,有誰知道如何阻止泄漏?

編輯

這是連接()的代碼:

private static ADODB.Connection _conn = new ADODB.Connection(); 

public static bool Connected 
{ 
    get { return _conn.State == 1; } 
} 

public static bool Connect() 
{ 
    lock (_conn) 
     if (!Connected) _conn.Open(Configuration.DB_ConnectionString, "", "", -1); 
    return Connected; 
} 
+0

Connect();'做什麼? – 2011-03-05 20:14:16

+0

我添加了代碼,包括所有相關的東西:) – Aidiakapi 2011-03-05 20:17:22

回答

2

你有沒有考慮過使用MySql .Net Connector?鑑於它是專門爲連接到MySql而設計的託管庫,它有更好的機會不泄漏。此外,我以前使用它,並沒有注意到它泄漏內存。

+0

我已經考慮過了,但我從來沒有使用過它,所以如果你能指出我正確的方向,它會很好:) – Aidiakapi 2011-03-05 20:18:38

+0

@Aidiakapi - I've鏈接到我的答案:)這是一些教程的鏈接:http://dev.mysql.com/doc/refman/5.1/en/connector-net-tutorials.html我強烈建議使用它,因爲它更好而不是ADODB的「通用」解決方案。出於好奇,你爲什麼在.net中使用ADODB? – Rob 2011-03-05 20:20:07

+0

我用過它,因爲我從ASP切換到ASP.Net xD,並且保留了很多舊代碼。 – Aidiakapi 2011-03-05 20:22:07

3

當從.Net使用COM時,您需要明確地釋放所使用的COM對象的任何句柄,否則它們將永遠留在內存中。

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 

因此,要重寫代碼:

object ret; 
ADODB.Recordset rs = null; 

Connect(); 

try 
{ 
    // Why the lock? Is your code sharing the same connection across threads? 
    lock (_conn) 
     rs = _conn.Execute(query, out ret, -1); 

    rs.Close(); 
} 
finally 
{ 
    if (rs != null) 
     System.Runtime.InteropServices.Marshal.ReleaseComObject(rs); 
} 

return (int)ret; 

您將需要保護_conn以同樣的方式,以確保您調用ReleaseComObject的時候完成它。

+0

謝謝我會記住,但我認爲最好是切換到託管代碼平臺:),謝謝:) – Aidiakapi 2011-03-05 20:45:57