C# 中的 ADODB 内存泄漏

发布于 2024-10-20 05:37:01 字数 1193 浏览 2 评论 0原文

在我的应用程序中,我使用 ADODB 查询 MySQL 数据库。这进行得很顺利,但是,ADODB 似乎泄漏了大量内存。

我通过调用每个执行查询的 close 方法部分修复了它。
我通过对这种方法的 1000000 个查询进行基准测试发现:

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 查询很有用。

那么,有谁知道如何阻止泄漏吗?

编辑

这是 Connect() 中的代码:

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;
}

In my application I'm using ADODB to query a MySQL database. This goes very smooth, however, ADODB seems to leak a lot of memory.

I fixed it partially by calling the close method of every executed query.
I found out by benchmarking 1000000 queries on this method:

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

After a about 10000 queries I was out of memory, extremely fast.

I figured it was because of the _conn.Execute, so I changed it into:

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;
}

Now, this seems to save a lot but it still leaks about 80MB of memory after executing 100000 queries.

Does anyone know how to stop it from leaking memory, I do NOT need the recordset. I have 3 different functions, one for executing like this, one for executing and returning a recordset wrapped in my own classes, and one for executing and returning the last inserted id, useful for INSERT INTO queries.

So, does anyone know how to stop the leak?

EDIT:

This is the code in Connect():

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

究竟谁懂我的在乎 2024-10-27 05:37:01

当使用 .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。

When working with COM from .Net, you need to explicitly release any handles to COM objects you've used, otherwise they'll stay in memory forever.

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

So to rewrite your code:

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;

You will need to protect _conn in the same way, ensuring you call ReleaseComObject when finished with it.

梦幻的心爱 2024-10-27 05:37:01

您是否考虑过使用MySql .Net Connector?鉴于它是一个专门为连接到 MySql 而设计的托管库,因此它更有可能不泄漏。另外,我以前使用过它,但没有注意到它泄漏内存。

Have you considered using the MySql .Net Connector? Given that it's a managed library which is designed specifically for connecting to MySql, it stands a better chance of not leaking. Also, I've used it previously and not noticed it leaking memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文