0

我们的 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类都继承自上面的这个基类,我们用一个块包围每个SqlConnection用法using

因此,例如,如果我们有一个Product表并且 aProductAccess继承了Access该类。

我们正在使用以下代码:

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

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

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

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

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

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

谢谢

4

1 回答 1

0

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

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

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

于 2013-09-29T16:05:12.423 回答