循环中的c#内存泄漏

时间:2012-03-23 21:07:34

标签: c# memory-leaks

 public void DoPing(object state)
    {
        string host = state as string;
        m_lastPingResult = false;
        while (!m_pingThreadShouldStop.WaitOne(250))
        {


                Ping p = new Ping();
                try
                {

                    PingReply reply = p.Send(host, 3000);
                    if (reply.Status == IPStatus.Success)
                    {

                        m_lastPingResult = true;
                    }
                    else { m_lastPingResult = false; }

                }
                catch { }
                numping = numping + 1;
            }


    }

知道为什么这段代码会给我一个内存泄漏?我可以看到这是代码,因为将等待值更改为更小或更大的值会增加内存使用率。有没有人知道如何解决它?或者如何查看代码的哪一部分导致它?

4 个答案:

答案 0 :(得分:4)

在一些垃圾收集语言中,如果创建它的方法仍未退出,则存在一个限制,即不收集该对象。

我相信.net在调试模式下以这种方式工作。引用本文;注意粗体陈述。

http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

  

考虑当前正在运行的方法中的局部变量   成为GC根。这些变量引用的对象总是可以   可以通过声明它们的方法立即访问,等等   他们必须保持在身边。这些根的寿命可以取决于   程序的构建方式。 在调试版本中,局部变量持续   只要该方法在堆栈上。在发布版本中,JIT   能够查看程序结构以找出最后一点   在执行过程中,方法可以使用变量   在不再需要时将丢弃它。这个策略不是   总是使用,可以关闭,例如,通过运行程序   在调试器中。

答案 1 :(得分:2)

垃圾收集仅在存在内存压力时才会发生,因此只是看到内存使用率上升并不意味着存在内存泄漏,在此代码中我看不出有什么可能存在合法泄漏。 您可以添加

GC.Collect();
GC.WaitForPendingFinalizers();

要仔细检查,但不应将其留在生产中。

编辑:评论中有人指出Ping是Disposable。不调用dispose会导致泄漏,最终会被清理,但可能需要很长时间,并导致与内存无关的问题。

答案 2 :(得分:2)

finally添加try-catch声明,如下所示:

catch() {}
finally
{
     Ping.Dispose();
}

答案 3 :(得分:1)

using(var p = new Ping())
{
    try
    {
        var reply = p.Send(host, 3000);

        if (reply.Status == IPStatus.Success)
           _lastPingResult = true;
        else  
           _lastPingResult = false; 
    }
    catch(Exception e)
    {
       //...
    }
}