发现内存泄漏了吗?

发布于 2024-12-12 08:34:45 字数 1255 浏览 0 评论 0原文

简而言之,当我的服务使用 sqlservr.exe 时,它​​就会发生内存泄漏。所以问题是,在哪里以及为什么! :(

我将我的连接初始化为空。并有一个finally子句来确保它们关闭...(我也尝试过在数据读取器上进行.dispose,但没有帮助)。

我已经尝试识别问题一天多了。所有我可以看出它就在某个地方

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();

    }
}

已解决:

  1. 没有泄漏。

    没有
  2. 我讨厌Sqlserver没有告诉我它缓存了内存 。连接时未使用是madee,所以只是增加和增加(直到需要为止)。

simply put, my sqlservr.exe is memory leaking when ever my service uses it. So the question is, Where and why! :(

I intialise my connection as nulls. and have a finally clause to ensure they are closed... (ive also tried .dispose on the datareader, but doesnt help).

I've tried identifying the problem for over a day. All I can tell is that it is here somewhere.

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();

    }
}

SOLVED:

  1. There is no leak.

  2. I hate Sqlserver for not telling me it caches memory that isnt in use when connections are madee, so just increases and increases (until it is needed).

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

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

发布评论

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

评论(4

小伙你站住 2024-12-19 08:34:45

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

内存占用不是确定性的,在您的示例中,只有当垃圾收集发生时,可执行文件使用的有效内存才会被释放,因此您可以看到内存增加,但这可能是不是问题,迟早会被收集,内存会恢复到适当的值。

看到评论后,问题似乎不在你的C#代码中(如果使用using关键字也是个好主意!),如果有问题...

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

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

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

问候

马西莫

Refactor your code with this keyword: using

Memory occupation is not deterministic, in you sample the effective memory used by the executable will be freed only when Garbage Collection occurs, so you can see memory increase but this could be not an issue, it will be collected sooner or later and memory will return to a proper value.

After seeing the comment, then the problem seems not to be in your C# code (also if using the using keyword it's a good idea!), if there is a problem...

SQL Server will increase memory occupation until it has memory available, it's designed to work that way. In your sample each time you pass a new where clause it will cache the SQL statement and so memory usage will increase until you have memory available.

In this case I suggest you to refactor your code to use at least SQL parameters to create the where clause, so the SQL will always remains the same and only the parameters change, this way SQL server will cache only one SQL statement and not thousands. Better yet is to create a stored procedure, but parameters are usually enough.

Keep also in mind that the way you're building your SQL statement is really unsafe and could lead to SQL injection attacks, using parameters will fix that too.

Regards

Massimo

婴鹅 2024-12-19 08:34:45

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

SqlConnection 的 Dispose 实现会在释放之前关闭连接。因此最好是使用 using 命令进行连接,您可以确定问题不会出在那里。

但由于您不保存引用,因此无论如何它都应该被垃圾收集,所以并不是真正的问题。你100%确定内存泄漏就在这里吗?

your Conenction sqlConCount is never really disposed.

the Dispose implementation of SqlConnection closes the connection before disposing. so the best would be to use a using command for the connection and you can be sure that the problem wont lie there.

but as you dont save a reference it should be anyway garbage collected, so not really a problem. are you 100% sure the memory leak is in here?

梦言归人 2024-12-19 08:34:45

看起来您在finally 块有机会触发之前返回了整数。尝试在try块中分配它并在finally块之后返回它

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

It looks like you're returning your integer before finally block has a chance to fire. Try assigning it in try block and return it after the finally block

int value = o;
try
{
  ... 
  value = Convert.ToInt32(dataCount["Count"]);
}
finally
{
//close connection
}
return value;
北城半夏 2024-12-19 08:34:45

我认为 string + string 会导致泄漏,请切换到 StringBuilder。您也没有处理 SqlConCountdataCount (您可以尝试使用 using 重构您的代码

i think string + string causes leaking, swtich to StringBuilder. also you're not disposing SqlConCount and dataCount (you could try to refactor your code using using

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