Есть ли событие, когда сборка мусора происходит в .NET? - PullRequest
15 голосов
/ 09 сентября 2010

У меня странное замедление на моем веб-сайте ASP.NET, которое я не могу отследить. Я подозреваю, что GC может начать работу и остановить мои темы. Чтобы знать наверняка, было бы хорошо регистрироваться каждый раз, когда GC действительно происходит.

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

Есть идеи?

Добавлено: Среда VS2008 / .NET 3.5 SP1. И нет, Уведомления о сборке мусора не подойдут, потому что они являются методом опроса и не работают для одновременного сбора мусора.

Ответы [ 5 ]

9 голосов
/ 09 сентября 2010

Вот простой трюк. Возможно, он не на 100% точен, но, вероятно, будет достаточно хорош.

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

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

Вот такой объект:

public class GCNotifier
{
    public static event EventHandler GarbageCollected;

    ~GCNotifier()
    {
        if (Environment.HasShutdownStarted)
            return;
        if (AppDomain.CurrentDomain.IsFinalizingForUnload())
            return;
        new GCNotifier();
        if (GarbageCollected != null)
            GarbageCollected(null, EventArgs.Empty);
    }

    public void Start()
    {
        new GCNotifier();
    }
}

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

Надеюсь, это поможет.

2 голосов
/ 09 сентября 2010

Простой ответ: «Нет, нет событий GC, только функция GCNotification». Тем не менее, вы создаете класс-оболочку, который будет прослушивать GCNotification, и эта оболочка может вызывать события, но не существует такого простого решения, как вы ищете.

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

2 голосов
/ 09 сентября 2010

Perhpas эта статья (Уведомления о сборке мусора) поможет.

вы можете получить уведомление о приближении полной сборки мусора

1 голос
/ 09 сентября 2010

Возможно, вы захотите прочитать эту статью на Мониторинг производительности ASP.NET и когда оповещать администраторов

Он включает в себя раздел о счетчиках GC, на котором можно посмотреть и что означают значения. Например

% Время в ГХ. Процент времени потратил на выполнение последнего мусора коллекция. Среднее значение 5% или меньше будет считаться здоровым, но шипы больше, чем это не редкость. Обратите внимание, что все темы приостановлено во время сбора мусора.

Возможно, вы также захотите взглянуть на блог. Если он сломан, исправьте его, вам следует В нем есть несколько примеров, в которых пошагово описывается, как определить конкретную проблему. Например, Пример использования ASP.NET: высокая загрузка ЦП в ГХ - большие объекты и высокая скорость выделения

1 голос
/ 09 сентября 2010

Мониторите ли вы perf-mon? Вы можете наблюдать за процессором - в целом и за процессом, .NET-памятью, включая размер каждого поколения и количество типов GC. Вы также можете позволить perf-mon работать и регистрироваться в течение длительных периодов времени, чтобы посмотреть на тренды. Я считаю, что это гораздо полезнее, чем дискретное «это происходит прямо сейчас!» события.

...