2012-11-24 3 views
7

जब मैं तर्कHotSpots संकलन लॉग टाइम को प्रबंधन के लिए अलग क्यों हैं Factory.getRuntimeMXBean()। GetUptime()?

-XX:+PrintCompilation 
साथ JVM शुरू

उत्पादन इस तरह है:

60 1    java.lang.String::hashCode (55 bytes) 
74 2    sun.nio.cs.UTF_8$Encoder::encode (361 bytes) 

पहले कॉलम मैं चाहता हूँ मिलीसेकंड में समय स्टाम्प, जब लॉग मुद्रित किया गया था है, और

long jvmUpTime = ManagementFactory.getRuntimeMXBean().getUptime(); 

या

: मूल्य कि ManagementFactory.getRuntimeMXBean().getUptime() द्वारा दिया जाता है करने के लिए इस समय स्टाम्प की तुलना
long jvmStartTime = ManagementFactory.getRuntimeMXBean().getStartTime(); 

लेकिन मेरी परिणाम इस तरह है:

[62:log from Java code] 
103 5    benchmark.AbstractBenchmarkST::benchmark (82 bytes) 
[62:log from Java code] 

ऐसा लगता है वहाँ के बारे में 40 उन दोनों के बीच एमएस अंतर है, जो दो समय टिकटों अतुलनीय बनाता है। किसी भी विचार से निपटने के लिए कैसे?

+3

कौन सा कोड लिख रहा है '[62: लॉग ...' दो बार? – fglez

उत्तर

0

लघु उत्तर

समय हॉटस्पॉट JIT संकलन लॉग के पहले कॉलम में मुद्रित (जब साथ JVM शुरू करने "-XX: + PrintCompilation" तर्क), समय से अधिक एक निरंतर अवधि का है ManagementFactory.getRuntimeMXBean() द्वारा प्राप्त किया गया। getUptime() (दिया गया है कि एक ही समय में प्राप्त किया जाता है जैसे संकलन लॉग मुद्रित होता है)।

यह कम से कम JDK 7 के लिए सच है विंडोज 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

ई हालांकि प्रबंधनFactory.getRuntimeMXBean()। getUptime() मुद्रित जेआईटी संकलन के बाद बुलाया गया था, लौटाया गया समय पहले के आमंत्रण को इंगित करता है।

ऐसा लगता है कि उनके पास लगभग 40 एमएस अंतर है, यह अंतर इसे अतुलनीय बनाता है। किसी भी विचार से निपटने के लिए कैसे?

चूंकि समय अंतर स्थिर है और एक JVM चलाने के दौरान नहीं बदला जाना चाहिए, तब तक किसी को भी समय की तुलना करने में सक्षम होना चाहिए, जब तक कि कोई समय में अंतर नहीं लेता।

लांग उत्तर

"-XX: + PrintCompilation" JVM तर्क शायद ही दर्ज है और एक ही अनुमान लगा सकते हैं, कि पहले कॉलम JVM की स्टार्टअप के लिए एक समय स्टाम्प रिश्तेदार प्रतिनिधित्व करता है। यदि किसी ने हॉटस्पॉट कंपाइलर के स्रोत कोड को देखा है, तो यह स्पष्ट हो जाता है कि प्रिंटकंपिलेशन द्वारा मुद्रित समय और प्रबंधन Factory.getRuntimeMXBean() द्वारा लौटाए गए समय। GetStartTime() दो अलग-अलग अलग-अलग समय टिकटें संदर्भित करता है जो दोनों प्रारंभिक होते हैं जेवीएम की स्टार्टअप।

संकलन लॉग 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()); 
} 

ओएस :: elapsed_counter() के दौरान :: init() ओएस कॉल द्वारा प्रारंभ बदले में हो जाता है startup of the JVM:

jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { 
    [...] 
    os::init(); 
    [...] 
} 

जावा विधि ManagementFactory.getRuntimeMXBean() getStartTime()। पर दूसरी ओर VMManagementImpl.java में एक देशी विधि को संदर्भित:

public native long getStartupTime(); 

जो VMManagementImpl.c में कार्यान्वित किया जाता है और JmmInterface लगातार झामुमो-समय देता है _JVM_INIT_DONE_TIME_MS:

management.cpp:

case JMM_JVM_INIT_DONE_TIME_MS: 
     return Management::vm_init_done_time(); 

जो JVM के बाद कुछ समय के ओएस :: init (शुरुआत के दौरान प्रारंभ हो जाता है) पहले से ही बुलाया गया था:

jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { 
    [...] 
    os::init(); 
    [...] 
    // record VM initialization completion time 
    Management::record_vm_init_completed(); 
    [...] 
} 

इसलिए समय मुद्रित जेआईटी संकलन लॉग द्वारा प्रबंधनFactory.getRuntimeMXBean() द्वारा प्राप्त समय से अलग है। getStartTime()।

संबंधित मुद्दे