Как может Java-программа обнаружила, что пережила долгую GC-паузу? - PullRequest
0 голосов
/ 30 сентября 2018

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

Как я могу заставить его контролировать сам?Я не хочу анализировать журналы GC.

JMX предоставляет LastGcInfo, но я не знаю, когда его запрашивать.

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

@ Ответ Jigar показывает, как вы можете отслеживать события GC.Однако я не думаю, что это позволило бы потоку измерить, как долго он ... или другой поток ... был приостановлен.

И на самом деле, я подозреваю, что нет способа измеритьэто.

Действительно, я не думаю, что есть способ измерить и другие виды пауз;например,

  • паузы из-за ожидания при вводе-выводе
  • паузы из-за синхронизации или
  • паузы из-за квантования времени, управляемого ОС.

Я не думаю, что то, что вы хотите сделать, выполнимо, не говоря уже о желательности.


Рассматривая ваши требования:

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

  1. SLA, вероятно, не составлен в терминах пауз GC 1 .Это будет сформулировано с точки зрения времени отклика.Это имеет большое значение.Время отклика намного проще измерить, чем паузы ГХ.

  2. Маловероятно, что SLA говорит, что вам нужно измерить время отклика (или что-то еще) в самом приложении.Поэтому измерьте его снаружи:

    • Анализ событий журнала приложения / веб-контейнера в отдельной системе мониторинга в реальном времени;например, Nagios, CheckMk, и так далее.
    • Сканирование файлов журнала приложения / веб-контейнера по факту.
    • Подключите мониторинг пакетов или потоков к чему-то, что записывает время отклика.

Если вы решите игнорировать 2), учтите, что любая дополнительная инфраструктура, которую вы добавите в свое Java-приложение для «самоконтроля», сделает его более сложным, и (еслиВы осторожны) добавьте к загрузке ГХ, делая паузы ГХ более частыми .

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


1 - Если это так, то кто-то допустил ошибку при написании / согласовании SLA!

0 голосов
/ 30 сентября 2018

Прежде чем перейти непосредственно к платному приложению Java APM или специальным реализациям, взгляните на Glowroot .

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

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

Попробуйте (это demo ), затем выберите APM, который соответствует вашим потребностямлучше.

0 голосов
/ 30 сентября 2018

Не рекомендуется, чтобы приложение обрабатывало GC-контроль в пространстве кода пользователя.Иногда приложение находится в состоянии (близком к OOM), где оно не сможет выполнить пользовательский код, и мониторинг может остаться неработоспособным.

Если вы все равно хотите это сделать (на свой страх и риск), вы можетеподключите слушателей к GC вот так и проверьте продолжительность GC.

for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
    NotificationEmitter emitter = (NotificationEmitter) gcBean;
    emitter.addNotificationListener(new CustomNotificationListener(), null, null);
}

и

class CustomNotificationListener implements javax.management.NotificationListener {
        @Override
        public void handleNotification(Notification notification, Object handback) {
            // hook your logic here.
          String notifType = notification.getType();
          if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
              // retrieve the garbage collection notification information
              CompositeData cd = (CompositeData) notification.getUserData();
              GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
              System.out.println(info.getGcInfo().getDuration());
          }
        }
}
...