问题
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:
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));
}
来源:https://stackoverflow.com/questions/57116971/how-do-i-extract-a-timestamp-from-the-heap-dump