2011-03-05 93 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