C# 发现内存泄漏了吗?

C# 发现内存泄漏了吗?,c#,memory-leaks,C#,Memory Leaks,简单地说,每当我的服务使用sqlservr.exe时,它都会发生内存泄漏。所以问题是,在哪里,为什么!:( 我将我的连接初始化为空。并且有一个finally子句来确保它们已关闭…(我也尝试过在datareader上进行处理,但没有帮助) 我已经试着找出这个问题一天多了。我能说的就是它就在这里的某个地方 private Int32 GetCount(String From, String Where) { //Build SQL string from given parameters.

简单地说,每当我的服务使用sqlservr.exe时,它都会发生内存泄漏。所以问题是,在哪里,为什么!:(

我将我的连接初始化为空。并且有一个finally子句来确保它们已关闭…(我也尝试过在datareader上进行处理,但没有帮助)

我已经试着找出这个问题一天多了。我能说的就是它就在这里的某个地方

private Int32 GetCount(String From, String Where)
{

    //Build SQL string from given parameters.
    String sql = "SET dateformat DMY SELECT COUNT(*) as Count FROM " + From + " WHERE " + Where;
    SqlDataReader dataCount = null;
    SqlCommand sqlCommCount = null;
    SqlConnection sqlConCount = null;
    try
    {
        sqlCommCount = new SqlCommand();
        sqlConCount = new SqlConnection();
        sqlCommCount.Connection = sqlConCount;
        sqlConCount.ConnectionString = "connectionstring";
        sqlCommCount.CommandText = sql;
        sqlConCount.Open();

        dataCount = sqlCommCount.ExecuteReader();
        while (dataCount.Read())
        {
            return Convert.ToInt32(dataCount["Count"]);
        }
        return 0;
    }
    finally
    {
        sqlConCount.Close();
        sqlCommCount.Dispose();
        if (dataCount != null)
            dataCount.Close();

    }
}
已解决:

  • 没有泄漏

  • 我讨厌Sqlserver不告诉我它缓存连接时不使用的内存,所以只会不断增加(直到需要为止)

  • 您的Conenction sqlConCount从未真正处理过

    SqlConnection的Dispose实现在Dispose之前关闭连接。因此,最好对连接使用using命令,您可以确保问题不会出现


    但是,由于您不保存引用,它应该被垃圾收集,所以这不是一个真正的问题。您100%确定内存泄漏在这里吗?

    我认为
    string+string
    会导致泄漏,切换到StringBuilder。而且您没有处理
    SqlConCount
    dataCount
    (您可以尝试使用
    重构代码,使用

    在finally块有机会触发之前返回整数。请尝试在try块中分配它,并在finally块之后返回它。)

    int value = o;
    try
    {
      ... 
      value = Convert.ToInt32(dataCount["Count"]);
    }
    finally
    {
    //close connection
    }
    return value;
    

    使用以下关键字重构代码:使用

    内存占用是不确定的,在您的示例中,可执行文件使用的有效内存将仅在垃圾收集发生时释放,因此您可以看到内存增加,但这可能不是问题,它迟早会被收集,内存将返回到正确的值

    看到评论后,如果出现问题,那么问题似乎不在C代码中(如果使用using关键字也是个好主意!)

    SQL Server将增加内存占用,直到有可用内存为止,它的设计就是这样。在您的示例中,每次传递新的where子句时,它都会缓存SQL语句,因此内存使用量将增加,直到有可用内存为止

    在这种情况下,我建议您重构代码,至少使用SQL参数来创建where子句,这样SQL将始终保持不变,只有参数发生更改,这样SQL server将只缓存一条SQL语句,而不是数千条。更好的做法是创建一个存储过程,但参数通常就足够了

    还要记住,构建SQL语句的方式确实不安全,可能会导致SQL注入攻击,使用参数也可以解决这一问题

    问候


    Massimo

    如果您的服务器真的发生泄漏,那么我们在这段客户端代码中找不到。很抱歉,我们懒得给出正确的答案,但是“使用”块是处理IDisposables的更好方法,而不是尝试/捕获/最终操作。在上面的代码中,您没有处理SqlDataReader,我不认为您的连接也正在被释放。正如其他一些答案所指出的,您应该使用'using'关键字,以便自动释放对象。另外,您如何知道您有内存泄漏?您是如何确定的?使用资源管理器,它只是不断上升。Sqlservr是数据库。这是我的Web服务代码,connec正在关闭数据库。某些内容未关闭,或导致sqlservr.exe上的内存上升(且从未下降)。我将尝试使用,这听起来是一个更好的主意。@Doomsknight:在其配置中,SQL Server允许使用多少内存?它是否停止在该限制下增加?您是否通过对每个调用执行与
    中的相同的
    来对该方法进行基准测试?最终将以任何方式调用,即使您在Tha returnAye,它无论如何都会执行。我做了检查,只是为了确保这不是问题:)“字符串+字符串”不会导致内存泄漏。在本例中,使用StringBuilder不会有任何好处。每个人都知道串联会分配一个新对象并将数据复制到该对象。这是真的。这不是内存泄漏。非常确定。我调用了此方法(根本不运行任何其他代码!)我的sqlservr.exe不断上升,直到我开始哭泣:(.使用资源管理器,sqlservr.exe不断上升。我已经打开它一段时间了,但它从来没有停止过。当这个Web服务开始被调用100到1000次,没有服务器重新启动时,它将耗尽内存。字符串“where”是根据传入的参数构建的,这只是我用来重用的一种方法。防止代码重复。我已经对我的字符串参数应用了某种sql注入预防。希望我的团队的另一名成员能够对其进行QA,以确保我正确地执行了该操作。感谢您指出这一点。