javajfrjava-mission-control

Dump part of Java Flight Record


Suppose I have configured a continuous flight record for my JVM using the following flags

java
-XX:StartFlightRecording=disk=false,dumponexit=true
-XX:FlightRecorderOptions=memorysize=200m
-jar
....

As far as I understand, this configuration stores up to 200mb in memory of hotspot events, discarding the oldest when the limit is reached.

To dump the record I'm using JFR.dump command via jcmd. There's also an alternative way to extract the recording via mission control, but due to a bug in it, I had no success extracting a record that was running outside mission control's JVM. Surprisingly, MBean server management works fine.

Regardless, I saw that it is possible to specify interval range to dump from a continuous recording via "Dump" functionality via mission control, for example from 2021-01-01 13:00:00 to 2021-01-01 14:00:00. Assume current time is 2021-01-02 17:00:00. How do I specify same interval via JFR.dump? Looking at JFR.dump reference, there aren't any flags to do that. So how does mission control do it?

Note: I'm using JMC 8 and Oracle JDK 11 0 10u8.


Solution

  • Unfortunately, the link you have ranks high in search engines, but it is six years old. You can find the latest documentation here (JDK 16), which is very much the same as JDK 11.

    It's not possible to dump part of a memory-based recording. In your example, you have to remove 'disk=false' and -XX:FlightRecorderOptions, and add 'maxsize=200M' to -XX:StartFlightRecording:

    $ java -XX:StartFlightRecording:maxsize=200M -jar ...
    

    Then you can do:

    $ jcmd <pid> JFR.dump begin=2021-01-01T13:00:00 end=2021-01-01T14:00:00
    

    The date time format is ISO-8601, which is what LocalDataTime.toString() and Instant.toString() produces.

    If you omit the end time, JFR.dump will assume it should end when you do the dump, and if you specify a relative time, it will be relative to the dump time.

    For example, to dump the last hour:

    $ jcmd <pid> JFR.dump begin=-1h
    

    You can also use the maxage parameter to limit the data, for example:

    $ jcmd <pid> JFR.dump maxage=1h
    

    The maxsize parameter can be used to specify how much data to include, for example:

    $ jcmd <pid> JFR.dump maxsize=50MB
    

    Another alternative is to create two disk-based recordings:

    $ java -XX:StartFlightRecording:maxsize=200M,name=sized
           -XX:StartFlightRecording:maxage=1h,name=aged 
           -jar ...
    
    $ jcmd <pid> JFR.dump name=aged 
    

    The overhead of two recordings are the same as one.

    (I wouldn't be too concerned about overhead of a disk-based recording. All data in JFR is written lock-free and flushed by a background thread. The difference in overhead between disk and memory is usually not measurable)