C# 和 SQL Server SqlConnection 使用导致内存泄漏

本文关键字:内存 泄漏 SQL Server SqlConnection | 更新日期: 2023-09-27 18:33:10

我们的 C# 应用程序中出现了严重的内存泄漏。我们隔离了所有可能的嫌疑人,发现数据层 - SqlConnection - 导致内存泄漏。我们正在执行许多SqlConnection请求。每秒大约 10 个请求。我们每天泄漏200M。

我们将以下SqlConnection访问作为基类:

public class Access : IDisposable
{
    protected SqlConnection connection;
    private readonly object locker = new object();
    protected void OpenConnection()
    {
        if (this.connection == null)
        {
            lock (locker)
            {
                if (this.connection == null)
                {
                    string conn = Config.Data["data"]["mainConnString"];
                    this.connection = new SqlConnection(conn);
                    this.connection.Open();
                }
            }
        }
        else if (this.connection.State == System.Data.ConnectionState.Closed)
        {
            lock (locker)
            {
                if (this.connection.State == System.Data.ConnectionState.Closed)
                {
                    this.connection.Open();
                }
            }
        }
    }
    public void Dispose()
    {
        if (this.connection != null)
        {
            this.connection.Close();
            this.connection.Dispose();
        }
    }
}

我们所有的SqlConnection类都继承自上面的这个基类,我们用一个using块包围每个SqlConnection

因此,例如,如果我们有一个Product表和一个ProductAccess继承Access类。

我们使用以下代码:

using (var acceess = new ProductAccess ())
{
    Product product = acceess .GetProductById (id);
}

因此,每次我们使用SqlConnection时,我们都会创建一个新的,并在完成使用它后将其处理掉(因为用法被using块包围(

我们使用的是 c# v4.0.30319 和 Microsoft SQL Server 2008 R2。

任何人都知道或有任何想法为什么会发生此内存泄漏?

也许它与垃圾回收问题或垃圾回收配置有关?

也许此泄漏与SqlConnection dispose()方法调用GC.SuppressFinalize(this)方法调用有关?

谢谢

C# 和 SQL Server SqlConnection 使用导致内存泄漏

几年前我遇到了这个问题。我意识到这是关于连接池的。正如MSDN所说:

"连接池减少了必须打开新连接的次数。池程序维护物理连接的所有权。它通过为每个给定的连接配置保持一组活动连接来管理连接。

可以在连接关闭后清除池(繁重且效率低下(,也可以通过尝试和错误将连接字符串中的Min Pool SizeMax Pool Size设置为最佳值。我相信在你的情况下,调整Max Pool Size更重要。尝试减少它并观察结果。最好从最小值和最大值= 1开始并进行测试;尽管这可能会损害性能。我希望这有所帮助。