c # утечка памяти в цикле - PullRequest
0 голосов
/ 24 марта 2012
 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 ]

4 голосов
/ 24 марта 2012

В некоторых языках сбора мусора есть ограничение, что объект не собирается, если метод, который его создал, все еще не завершился.

Я полагаю, что .net работает таким образом в режиме отладки. Цитирование из этой статьи; обратите внимание на выделенное жирным шрифтом утверждение.

http://www.simple -talk.com / DotNet / .net-основа / understanding-garbage-collection-in-.net /

Локальная переменная в методе, который в данный момент выполняется быть корнем GC. Объекты, на которые ссылаются эти переменные, всегда могут сразу же получить доступ к методу, в котором они объявлены, и так они должны быть вокруг. Время жизни этих корней может зависеть от способ, которым была построена программа. В сборках отладки локальная переменная сохраняется до тех пор, пока метод находится в стеке. В сборках выпуска JIT умеет смотреть на структуру программы, чтобы проработать последний пункт в ходе выполнения, что переменная может использоваться методом и откажется от него, когда он больше не требуется. Эта стратегия не всегда используется и может быть отключен, например, запустив программу в отладчике.

2 голосов
/ 24 марта 2012

Добавьте оператор finally к вашему try-catch, например:

catch() {}
finally
{
     Ping.Dispose();
}
2 голосов
/ 24 марта 2012

Сборка мусора происходит только при нехватке памяти, поэтому простое наблюдение за использованием вашей памяти не означает, что произошла утечка памяти , и в этом коде я не вижу, как может быть допустимая утечка. Вы можете добавить

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

для двойной проверки, но не должны оставлять это в работе.

Редактировать: кто-то в комментариях указал, что Ping является Одноразовым.не вызывая утилизацию может привести к утечкам, которые в конечном итоге будут очищены, но это может занять много времени и вызвать проблемы, не связанные с памятью.

1 голос
/ 24 марта 2012
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)
    {
       //...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...