c# memory leak in loop

2019-09-09 00:44发布

 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;
            }


    }

Any idea why this code gives me a memory leak? I can see it's this code as changing the wait value to smaller or larger values increases the rate of the memory usage. Does any one have any idea how to resolve it? or how to see what part of the code is causing it?

4条回答
仙女界的扛把子
2楼-- · 2019-09-09 01:16

Garbage collection only happens when there is memory pressure, thus just seeing your memory usage go up doesn't mean there is a memory leak and in this code I don't see how there could be a legitimate leak. You can add

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

to double check but shouldn't leave that in production.

Edit: someone in comments pointed out that Ping is Disposable. not calling dispose can cause leaks that will eventually get cleaned up but may take a long time and cause non memory related problems.

查看更多
做个烂人
3楼-- · 2019-09-09 01:18
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)
    {
       //...
    }
}
查看更多
Explosion°爆炸
4楼-- · 2019-09-09 01:33

Add a finally statement to your try-catch, like this:

catch() {}
finally
{
     Ping.Dispose();
}
查看更多
We Are One
5楼-- · 2019-09-09 01:37

In some garbage collected languages, there is a limitation that the object isn't collected if the method that created it still hasn't exited.

I believe .net works this way in debug mode. Quoting from this article; note the bolded statement.

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

A local variable in a method that is currently running is considered to be a GC root. The objects referenced by these variables can always be accessed immediately by the method they are declared in, and so they must be kept around. The lifetime of these roots can depend on the way the program was built. In debug builds, a local variable lasts for as long as the method is on the stack. In release builds, the JIT is able to look at the program structure to work out the last point within the execution that a variable can be used by the method and will discard it when it is no longer required. This strategy isn’t always used and can be turned off, for example, by running the program in a debugger.

查看更多
登录 后发表回答