How do I extract a timestamp from the heap dump

1.8k Views Asked by At

Unfortunately, I forgot to record the time that I took the heap dump. I hope that somewhere in the heap, the standard library caches something like System.currentTimeMillis(). Unfortunately, I do not have any business objects that cache it.

One difficult option I have it to browse all the threads, and see if their local variables stored a timestamp somewhere. However, this is not technique I can apply to all heap dumps.

I looked at java.lang.System in openJDK and it doesn't look like we cache a value. We go to native code to get the current time, but we don't store the result from native code anywhere. https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/4d891c8db5c1/src/share/classes/java/lang/System.java

1

There are 1 best solutions below

0
Holger On BEST ANSWER

The heap dump file contains a timestamp right in its header. But there is a zero-terminated string at the beginning, which would make the exact position of the timestamp dynamic, if the string wouldn’t be always the same.

So for a short, ad-hoc lookup in your actual files, you might simply assume the usual position and extract the timestamp as

try(RandomAccessFile raf = new RandomAccessFile(hprofFileLocation, "r")) {
    raf.seek(23);
    System.out.println(hprofFileLocation+" created "+Instant.ofEpochMilli(raf.readLong()));
}

whereas a clean solution would read the zero terminated string, skip the subsequent int value and read the timestamp from the resulting position, e.g.

try(FileChannel fch = FileChannel.open(
                          Paths.get(hprofFileLocation), StandardOpenOption.READ)) {
    ByteBuffer bb = fch.map(
        FileChannel.MapMode.READ_ONLY, 0, Math.min(Integer.MAX_VALUE, fch.size()));
    do {} while(bb.get() != 0); // zero terminate string, usually "JAVA PROFILE 1.0.[12]"
    int pointerSize = bb.getInt();
    long timeStamp = bb.getLong();
    System.out.println(hprofFileLocation+" created "+Instant.ofEpochMilli(timeStamp));
}