Утечка памяти происходит при использовании потока внутри другого потока - PullRequest
1 голос
/ 02 декабря 2010

Ниже пример кода имеет утечку памяти. Если я закомментирую две строки внутри RefreshTimer_Elapsed, утечка памяти исчезнет. Кто-нибудь знает, что не так? Спасибо за помощь.

    static void RefreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Thread innerThread = new Thread(delegate() { });
        innerThread.Start();
    }

    static void Main(string[] args)
    {
        System.Timers.Timer RefreshTimer = new System.Timers.Timer();
        RefreshTimer.Interval = 5000;
        RefreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(RefreshTimer_Elapsed);
        RefreshTimer.Start();

        for (; ; )
        { }           
    }

Ответы [ 6 ]

3 голосов
/ 02 декабря 2010

То, что вы видите, может быть просто ресурсами, которые еще не возвращены сборщиком мусора из-за отсутствия нагрузки на память.

Кроме того, у вас в цикле Main есть занятое для цикла, вам, вероятно, нужен оператор Thread.Sleep для тестирования, если только это не является частью этого теста ...

Чтобы запустить сборку мусора только для тестирования, вы можете заменить цикл for на:

while(true)
{
 Thread.Sleep(5000);
 GC.Collect();
 GC.WaitForPendingFinalizers();
}

В общем, при рассмотрении «утечек памяти» или проблем с ресурсами в управляемом коде я бы рекомендовал использовать профилировщик (т. Е. Redgate ANTS ) и более внимательно посмотреть на распределение во времени.

3 голосов
/ 02 декабря 2010

Вы уверены, что есть утечка памяти? Или вы замечаете, что ваша память только растет?

Пока сборщик мусора не очистит все созданные вами потоки, память будет расти, но она не протекает, сборщик мусора знает, что это мертвая память.

Единственный способ «утечки» памяти в управляемой среде, такой как .NET или Java, - это когда у вас есть ссылки на объекты, которые никогда не используются или не нужны. Это не тот случай, здесь. Вы просто создаете кучу потоков и сразу же забываете о них. Как только на них больше не ссылается RefreshTimer_Elapsed и поток перестает работать, тогда больше нет ссылок, и они свободны для очистки.

Вы не увидите падение памяти, пока сборщик мусора не будет готов выполнить очистку. Вы можете попытаться форсировать это, но это не рекомендуется для повышения производительности.

1 голос
/ 02 декабря 2010

Я думаю, это потому, что вы продолжаете создавать новые темы.

0 голосов
/ 06 декабря 2010

RefreshTimer_Elapsed создает новый поток каждый интервал. Какую работу выполняет анонимный метод? Это завершает? Каждый созданный вами поток получит 1 МБ виртуальной памяти, выделенной через Windows.

Если ваши потоки никогда не заканчиваются, то каждый интервал вы будете использовать еще 1 МБ памяти.

0 голосов
/ 02 декабря 2010

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

0 голосов
/ 02 декабря 2010

Объект Timer должен быть удален!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...