簡短回答
在熱點JIT編譯日誌中的第一列中打印的時間(與啓動JVM當「-XX:+ PrintCompilation」參數),是一個恆定的持續時間比所述時間大的由ManagementFactory.getRuntimeMXBean()。getUptime()返回(假設getUptime在編譯日誌打印的同時被調用)。
這至少是真實的JDK 7的Windows 7下運行,並可以通過執行以下代碼很容易地驗證「-XX:+ PrintCompilation」:
public static void main(String[] args) {
System.out.println("JVM uptime: " + ManagementFactory.getRuntimeMXBean().getUptime());
}
結果應該是這個樣子:
77 1 java.lang.String::hashCode (55 bytes)
79 2 java.lang.String::indexOf (70 bytes)
80 3 java.lang.String::charAt (29 bytes)
82 4 java.lang.String::lastIndexOf (52 bytes)
82 5 java.lang.String::equals (81 bytes)
82 6 java.lang.AbstractStringBuilder::ensureCapacityInternal (16 bytes)
82 7 java.lang.String::indexOf (166 bytes)
85 8 n java.lang.System::arraycopy (native) (static)
JVM運行時間:43
ë雖然ManagementFactory.getRuntimeMXBean()。getUptime()在打印的JIT編譯之後被調用,但返回的時間似乎指向先前的調用。
看來他們有大約40毫秒的差異,這種差異使得它無法比擬。任何想法如何處理這個?
由於時間差是不變的,在運行JVM時不應改變,所以只要考慮時間差,就應該能夠比較時間。
長的答案
的「-XX:+ PrintCompilation」 JVM說法很難證明,一個只能猜測,第一列表示相對於JVM的啓動時間戳。如果查看HotSpot編譯器的源代碼,可以明顯看出,PrintCompilation輸出的時間和ManagementFactory.getRuntimeMXBean()。getStartTime()返回的時間引用了兩個完全不同的時間戳,這兩個時間戳同時被初始化JVM的啓動。
編譯日誌在通話過程中獲得打印到CompileTask::print_compilation_impl:
void CompileTask::print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
bool is_osr_method, int osr_bci, bool is_blocking,
const char* msg, bool short_form) {
if (!short_form) {
st->print("%7d ", (int) st->time_stamp().milliseconds()); // print timestamp
}
st->print("%4d ", compile_id); // print compilation number
[...]
}
ST-> TIME_STAMP()在ostream.cpp實現的,是指獲取與由操作系統返回的時間初始化的TimeStamp :: elapsed_counter ():
ostream.cpp:
void outputStream::stamp() {
if (! _stamp.is_updated()) {
_stamp.update(); // start at 0 on first call to stamp()
}
[...]
}
timer.cpp:
void TimeStamp::update() {
update_to(os::elapsed_counter());
}
OS :: elapsed_counter()又由呼叫初始化過程中獲取到OS ::的init()的startup of the JVM:
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
[...]
os::init();
[...]
}
Java方法ManagementFactory.getRuntimeMXBean()getStartTime()。另一方面是指在VMManagementImpl.java本地方法:
public native long getStartupTime();
其在VMManagementImpl.c實現,並且從JmmInterface恆定JMM返回時間_JVM_INIT_DONE_TIME_MS:
management.cpp:
case JMM_JVM_INIT_DONE_TIME_MS:
return Management::vm_init_done_time();
它被啓動了JVM的後相當長的一段時間OS ::初始化(中)初始化已經叫:
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
[...]
os::init();
[...]
// record VM initialization completion time
Management::record_vm_init_completed();
[...]
}
因此,打印時間通過JIT編譯日誌不同於ManagementFactory.getRuntimeMXBean()。getStartTime()返回的時間。
哪個代碼寫了'[62:log ...'兩次? – fglez