Reputation: 2835
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
Upvotes: 4
Views: 2226
Reputation: 111
Here is how I do it from the command-line using Perl:
perl -e '1 while ord getc; read STDIN, $_, 12; print scalar gmtime 0.001 * unpack "x4Q>"' <heapdump.hprof
It does the same as @holger's Java code, but no need to compile anything. The output is in GMT, but if you use localtime
instead of gmtime
you will get output in whatever your local timezone is.
Upvotes: 1
Reputation: 298539
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));
}
Upvotes: 5