Search code examples
javagarbage-collectionmonitor

How can a java program find itself has experienced a long GC pause?


I am writing a program that can have long GC pauses, however the SLA said I shouldn't have too many of them. And it needs to report if it finds any.

How can I make it monitor itself? I don't want to parse GC logs.

JMX exposes LastGcInfo, but I don't know when to query it.


Solution

  • It is not good idea to let application handle GC relate monitoring in user code space. Sometime application is in the state (close to OOM), where it won't be able to execute user code and monitoring can remain broken.

    If you want to do this anyways (at your risk), you can hook the listeners to GC like this and inspect GC duration.

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

    and

    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());
              }
            }
    }