Over a million developers have joined DZone.

Turning on GC Logging at Runtime

DZone's Guide to

Turning on GC Logging at Runtime

Free Resource

Build vs Buy a Data Quality Solution: Which is Best for You? Gain insights on a hybrid approach. Download white paper now!

There is always the next JVM behaving badly. And you know by heart that if you just could have had those few startup options exposing some more information about what is going on, you might have stood a chance of actually fixing the goddamn thing. But nope, exactly the flag you need (be it -XX:+HeapDumpOnOutOfMemoryError or -XX:+PrintGCDetails) is always missing.

So you shrug in grief, kill the suffering JVM, alter the startup parameters and pray that the problematic situation is reproduced after restart. Sometimes it does and now you might have enough evidence to actually go ahead and start fixing the underlying root cause.

The problem with the approach described is obvious – instead of a single outage, you need to go through an extra restart just to pick up those pesky debug options. As a matter of fact, there is a workaround available, adding which to your arsenal can prove to be beneficial on occasions.


There is a nice little utility well hidden in JDK bundles. jinfo is a command-line utility to harvest configuration information from a running Java process. The interesting part however, is that with the-flag option, the jinfo utility can dynamically adjust the value of certain Java VM flags for the specified Java process. The list of such flags is limited, but still helpful on occasions. The full list of such flags on your JVM can be checked via the following command:

my-precious me$ java -XX:+PrintFlagsFinal -version|grep manageable
     intx CMSAbortablePrecleanWaitMillis            = 100                                 {manageable}
     intx CMSWaitDuration                           = 2000                                {manageable}
     bool HeapDumpAfterFullGC                       = false                               {manageable}
     bool HeapDumpBeforeFullGC                      = false                               {manageable}
     bool HeapDumpOnOutOfMemoryError                = false                               {manageable}
     ... cut for brevity ...
     bool PrintGC                                   = false                               {manageable}
     bool PrintGCDateStamps                         = false                               {manageable}
     bool PrintGCDetails                            = false                               {manageable}
     bool PrintGCTimeStamps                         = false                               {manageable}

The -XX:+PrintFlagsFinal lists all the JVM options, out of which the “manageable” options are currently of interest. These are dynamically writeable through the JDK management interface (com.sun.management.HotSpotDiagnosticMXBean API). The very same MBean is also published through JConsole. To my liking, the command-line version is a lot more convenient though.

Example how to use jinfo

As an example of how to use jinfo, let us dynamically turn on the GC logging on a running JVM:

my-precious me$ jps
12278 HighAllocationRate
12279 Jps
12269 JConsole
my-precious me$ jinfo -flag +PrintGCDetails 12278
my-precious me$ jinfo -flag +PrintGC 12278
my-precious me$ 

The utility turned on the GC logging by turning on the -XX:+PrintGC and -XX:+PrintGCDetails options. The minor difference to the behaviour of command line parameters is in the fact that you have to specify both PrintGCDetails and PrintGC options via jinfo. In case you were setting the parameters via startup script, just -XX:+PrintGCDetails is necessary as it automatically turns on the -XX:+PrintGC.

Nevertheless, checking the standard output, the GC log of the 12278 PID started rolling nicely:

[GC (Allocation Failure) [PSYoungGen: 876416K->102624K(909312K)] 1094420K->320820K(1161216K), 0.2173131 secs] [Times: user=0.74 sys=0.00, real=0.22 secs] 
[GC (Allocation Failure) [PSYoungGen: 890304K->102240K(917504K)] 1108924K->320956K(1169408K), 0.2446639 secs] [Times: user=0.82 sys=0.01, real=0.25 secs] 

Turning the logging off is similar – you just need to invoke the jinfo -flag -PrintGCDetails 12278 andjinfo -flag -PrintGC 12278 commands to get rid of the log messages.

Equipping you with this knowledge, I can only hope it will save you a day or two down your troubleshooting career. Assuming you are not one of the happy users of performance monitoring tools such as Plumbr, in case of which you would not face such need in the first place.

Build vs Buy a Data Quality Solution: Which is Best for You? Maintaining high quality data is essential for operational efficiency, meaningful analytics and good long-term customer relationships. But, when dealing with multiple sources of data, data quality becomes complex, so you need to know when you should build a custom data quality tools effort over canned solutions. Download our whitepaper for more insights into a hybrid approach.


Published at DZone with permission of Nikita Salnikov-Tarnovski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}