GC запускает и останавливает события - PullRequest
7 голосов
/ 08 октября 2009

Разве нельзя получить событие, когда начинается GC? Я хочу рассчитать время каждого отдельного GC, чтобы я мог видеть, вызваны ли паузы на моем сервере GC или чем-то еще.

GC приостанавливает все потоки .NET во время работы, верно? (За исключением потока, на котором он работает, конечно). Как насчет неуправляемых тем?

Спасибо!

Ответы [ 7 ]

6 голосов
/ 08 октября 2009

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

По сути, вы создаете класс с финализатором, создаете объект этого класса и просто удаляете ссылку (т.е. не сохраняете ее). Затем объект будет оставлен до тех пор, пока GC не ударит его, где он будет завершен.

Хитрость заключается в том, что в финализаторе, который вы регистрируете (каким бы способом вы не захотели его использовать), запущен финализатор, и, если домен приложения не завершает работу, вы просто создаете новый объект, который вы быстро отбрасываете ссылка на, готов к следующему GC.

Это работает на удивление хорошо и не требует много работы с вашей стороны.

Вот класс, который я использую:

namespace PresentationMode
{
    /// <summary>
    /// This class is used to get a running log of the number of garbage collections that occur,
    /// when running with logging.
    /// </summary>
    public sealed class GCLog
    {
        #region Construction & Destruction

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="GCLog"/> is reclaimed by garbage collection.
        /// </summary>
        ~GCLog()
        {
            SiAuto.Main.LogMessage("GARBAGE COLLECTED");
            if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted)
                new GCLog();
        }

        #endregion

        #region Public Static Methods

        /// <summary>
        /// Registers this instance.
        /// </summary>
        public static void Register()
        {
#if DEBUG
            if (SiAuto.Si.Enabled)
                new GCLog();
#endif
        }

        #endregion
    }
}

Все, что вам нужно сделать, это вызвать метод .Register(). Обратите внимание, что я использую SmartInspect в качестве инструмента ведения журнала, поэтому вы хотите заменить вызовы, связанные с SiAuto, чем-то другим.

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

3 голосов
/ 08 октября 2009

Для этого предназначен API профилирования. См. ICorProfilerCallback2 :: GarbageCollectionStarted и GarbageCollectionFinished .

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

1 голос
/ 25 ноября 2010

.net 4 содержит событий сборки мусора , которые могут быть вам полезны.

1 голос
/ 08 октября 2009

ГХ не выдает никаких событий, но вы можете использовать таймер и вызвать GC.CollectionCount(), чтобы увидеть, когда произошла коллекция.

0 голосов
/ 07 августа 2010

Вы можете точно отслеживать и измерять приостановку работы ГХ, используя CLR Hosting . Вы можете найти пример именно этого в этом посте: Точное измерение подвесок ГХ .

0 голосов
/ 08 октября 2009

Счетчик производительности % Время в ГХ должен предоставить вам необходимые данные.

0 голосов
/ 08 октября 2009

неуправляемые потоки не зависят от ГХ.

Вы можете увидеть производительность ГХ в мониторе производительности, вот статья о том, как создать системный монитор. Я думаю, вы можете получить счетчик GC как-то.

Codeproject

Вот описание счетчиков перфокарт, используемых GC

GC-счетчики

...