GC Logging and Unified Logging
JVM unified logging provides a consistent way to inspect garbage collection and other runtime events, making it useful for understanding application behavior and validating JVM tuning changes. In modern Java, `-Xlog` controls unified logging output and can be configured by log level, tag, destination, and formatting.
Unified logging was introduced in Java 9 as a common logging framework for JVM components. Garbage-collection messages are exposed through logging tags such as `gc`, allowing operators to observe events without changing application code.
A basic configuration such as `-Xlog:gc` enables GC-related messages. More detailed diagnostics can be requested with combinations such as `-Xlog:gc*=debug`, where `*` includes related GC tags and `debug` increases verbosity. The exact amount of information depends on the selected tags, level, collector, and JDK implementation.
A unified-log selector has the general form `-Xlog:<what>:<output>:<decorators>:<output-options>`. The `what` section identifies tags and levels, the output selects destinations such as the console or a file, and decorators can add information such as timestamps, uptime, or thread identifiers.
For tuning work, GC logs are useful for comparing before-and-after behavior. A candidate should look at observable metrics such as pause durations, collection frequency, heap occupancy, and whether major collections occur under load rather than judging a tuning change from a single log line.
GC logging is diagnostic rather than a tuning mechanism by itself. Excessively verbose logging can increase output volume, so production configurations should select the information needed for the investigation and use an appropriate destination and rotation strategy.
Key points
- `-Xlog` is the unified JVM logging interface introduced in Java 9.
- GC events can be selected with tags such as `gc`.
- Logging selectors can specify tags, levels, outputs, and decorators.
- GC logs help measure pauses, collection frequency, and heap behavior.
- Compare GC behavior under representative workloads when evaluating JVM tuning changes.
Interview questions
What is JVM unified logging, and why is it useful for GC troubleshooting?
JVM unified logging is a common logging system for JVM components introduced in Java 9. It lets operators select events using tags and verbosity levels and send them to destinations such as the console or a file. For GC troubleshooting, it provides evidence about collections and pauses without requiring application-code changes. This makes it useful when measuring JVM behavior before and after a tuning change.
What does `-Xlog:gc` do?
`-Xlog:gc` selects the `gc` logging tag and enables its default informational logging. It is a simple way to observe garbage-collection activity from the JVM. More detailed configurations can select additional tags or increase the log level. The exact events and fields depend on the JDK and garbage collector in use.
How would you use GC logs to evaluate a JVM tuning change?
First, I would establish a baseline using a representative workload and collect relevant GC logs. After changing the JVM configuration, I would repeat the workload under comparable conditions and compare pause durations, collection frequency, heap occupancy, and application throughput or latency. I would avoid concluding that a change helped based on a single collection event. The goal is to connect JVM-level observations with application-level performance.
What does a unified logging selector contain?
A selector can describe what to log, where to send it, and how the records should be decorated. The `what` portion identifies tags and levels, while output and decorator settings control the destination and contextual information. For example, a configuration can select GC-related tags, write them to a file, and include timestamps. The syntax provides a composable way to control JVM diagnostics.
A service has long latency spikes. How could GC logging help investigate them?
I would correlate application latency spikes with GC events and pause durations over the same time interval. I would examine collection frequency, heap occupancy, and the behavior of the selected collector rather than assuming every latency spike is caused by GC. If a correlation appears, I would compare it against a controlled baseline and investigate allocation pressure, heap sizing, and collector configuration. I would also verify the result under representative production-like load before changing JVM settings.