JVM में JIT- संकलित कोड कैसे देखें?


84

क्या JVM में JIT द्वारा निर्मित मूल कोड को देखने का कोई तरीका है?


क्या आप वाकई JIT- संकलित (मूल) कोड या केवल बाइट-कोड देखना चाहते हैं? मैं पूछता हूं क्योंकि इस सवाल को पूछने से कुछ संदेह पैदा होते हैं यदि आप वास्तव में देशी कोड देखना चाहते हैं ... और, क्षमा करें, मुझे ऐसा कोई उपकरण नहीं पता है।
जिम्पफ

3
मैं निर्गमन JIT- संकलित मूल कोड देखना चाहता हूं। बेशक यह कुछ ऐसा नहीं है कि मुझे काम करने की ज़रूरत है, बल्कि तरह-तरह के प्रयोग और जाँच-पड़ताल करने की ज़रूरत है।
alsor.net 12

मामूली फ्रेम चुनौती: एक गतिशील संकलक जैसा कि आधुनिक जेवीएम में उपयोग किया जाता है , संकलित कोड का सिर्फ एक संस्करण नहीं होता है ; यह व्याख्या करना शुरू कर सकता है, फिर एक विधि या इसके कुछ भाग को संकलित कर सकता है, फिर संभावित रूप से इसे कई बार recompile करता है क्योंकि कक्षाएं लोड / अनलोड या उपयोग पैटर्न शिफ्ट या प्रदर्शन आँकड़ों के आधार पर प्राप्त होती हैं। , (मुझे लगता है कि यह और भी संकलित संस्करण त्यागने और व्याख्या पर लौट सकते हैं कि अगर फायदेमंद लगता है।) तो आप न केवल विभिन्न मशीनों, और न ही यहां तक कि एक ही मशीन पर विभिन्न रन पर अलग अलग कोड प्राप्त हो सकता है, लेकिन में अलग अलग समय पर एक ही रन ।
13

जवाबों:


45

मान लें कि आप सन हॉटस्पॉट JVM का उपयोग कर रहे हैं (अर्थात Oracle द्वारा java.com पर उपलब्ध कराया गया है ), आप ध्वज को जोड़ सकते हैं

-XX: + PrintOptoAssembly

अपना कोड चलाते समय यह जेआईटी संकलक द्वारा उत्पन्न अनुकूलित कोड को प्रिंट करेगा और बाकी को बाहर कर देगा।

यदि आप संपूर्ण बायोटेक देखना चाहते हैं, तो बिना चुने हुए भागों को शामिल करें

-XX: CompileThreshold = #

जब आप अपना कोड चला रहे हों।

आप इस आदेश और सामान्य रूप में JIT की कार्यक्षमता के बारे में अधिक पढ़ सकते हैं यहाँ


क्या यह विकल्प केवल डिबग बिल्ड या किसी भी चीज़ में मौजूद है? क्योंकि मेरा JVM ("जावा (TM)) एसई रनटाइम एनवायरनमेंट (बिल्ड 1.6.0_16-b01") इसे पहचान नहीं पाता है, भले ही वेब पर स्रोत इस सुविधा को Sun Java 6 और OpenJDK में उपलब्ध होने का संकेत दे।
Joachim Yauer

2
हां, DEBUG बायनेरी की जरूरत है। blogs.warwick.ac.uk/richardwarburton/entry/…
alsor.net

3
ऐसा नहीं होना चाहिए (आजकल) -XX: + PrintAssembly, कम से कम आजकल? मेरी मशीन पर परीक्षण किया गया है, और यहां जो कहा गया है उससे मेल खाता है: wikis.sun.com/display/HotSpotInternals/PrintAssembly आपको इसकी आवश्यकता है -XX: + UnlockDiagnosticVMOptions इस विकल्प और एक disassembler प्लगइन से पहले।
ब्लेसरॉब्लेड

@ ब्लेज़रब्लड मुझे मिल रहा है: वीएम ऑप्शन 'PrintAssembly' को बेहतर तरीके से निर्दिष्ट: जावा वर्चुअल मशीन नहीं बना सका। त्रुटि: एक घातक अपवाद हुआ है। कार्यक्रम से बाहर निकलेंगे।
कोरे तुगे

@KorayTugay अन्य उत्तर देखें - अपडेटेड लिंक wikis.oracle.com/display/HotSpotInternals/PrintAssembly है , जैसा कि stackoverflow.com/a/15146962/574 या stackoverflow.com/a/4149878/53974 में दिया गया है । यदि निम्नलिखित निर्देश काम नहीं करते हैं, तो कृपया कुछ उचित स्थान पर विवरण के साथ पूछें (यह सुनिश्चित नहीं है कि क्या यह आपके मामले के लिए एक और प्रश्न होना चाहिए, यह संदर्भित करते हुए)।
ब्लेसरॉब्लेड

76

सामान्य उपयोग

जैसा कि अन्य उत्तरों द्वारा समझाया गया है, आप निम्नलिखित JVM विकल्पों के साथ दौड़ सकते हैं:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

एक विशिष्ट विधि पर फ़िल्टर करें

आप निम्नलिखित सिंटैक्स के साथ एक विशिष्ट विधि पर भी फ़िल्टर कर सकते हैं:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

टिप्पणियाँ:

  • आपको ओएस आदि के आधार पर दूसरे तर्क को उद्धरण के भीतर रखने की आवश्यकता हो सकती है।
  • यदि विधि इनबिल्ट हो जाती है, तो आप कुछ अनुकूलन छोड़ सकते हैं

कैसे करें: विंडोज पर आवश्यक लाइब्रेरी स्थापित करें

यदि आप Windows चला रहे हैं, तो इस पृष्ठ पर निर्माण और स्थापित करने के निर्देश हैं hsdis-amd64.dllऔर hsdis-i386.dllजिन्हें इसे काम करने के लिए आवश्यक है। हम नीचे कॉपी करते हैं और संदर्भ के लिए उस पेज की सामग्री का विस्तार करते हैं:


प्रीबिलीट बायनेरिज़ कहाँ से लाएँ

आप fcml प्रोजेक्ट से विंडोज के लिए प्रीबिल्ट बायनेरी डाउनलोड कर सकते हैं

विंडोज का निर्माण hsdis-amd64.dllऔर निर्माण कैसे करेंhsdis-i386.dll

गाइड का यह संस्करण विंडोज 8.1 64 बिट पर 64-बिट Cygwin और hsdis-amd64.dll का उपयोग करके तैयार किया गया था

  1. सिगविन स्थापित करें । पर Select Packagesस्क्रीन, निम्न पैकेज को जोड़ने (विस्तार करके Develश्रेणी, तो पर एक बार क्लिक Skipप्रत्येक पैकेज के नाम के आगे लेबल):

    • make
    • mingw64-x86_64-gcc-core(केवल इसके लिए आवश्यक hsdis-amd64.dll)
    • mingw64-i686-gcc-core(केवल इसके लिए आवश्यक hsdis-i386.dll)
    • diffutils( Utilsश्रेणी में)
  2. सिगविन टर्मिनल चलाएं। यह इंस्टॉलर द्वारा बनाए गए डेस्कटॉप या स्टार्ट मेनू आइकन का उपयोग करके किया जा सकता है, और आपके साइगविन होम डायरेक्टरी ( C:\cygwin\home\<username>\या C:\cygwin64\home\<username>\डिफ़ॉल्ट रूप से) का निर्माण करेगा।

  3. नवीनतम GNU बिनुटिल्स स्रोत पैकेज डाउनलोड करें और अपनी सामग्री को अपनी Cygwin होम निर्देशिका में निकालें। लेखन के समय, नवीनतम पैकेज है binutils-2.25.tar.bz2। यह binutils-2.25आपके Cygwin होम निर्देशिका में (या जो भी नवीनतम संस्करण है) नाम की निर्देशिका में परिणाम होना चाहिए ।
  4. OpenDDK स्रोत को JDK 8 अपडेट रिपॉजिटरी में जाकर , अपने इंस्टॉल किए गए JRE संस्करण के अनुरूप टैग का चयन करके और bz2 पर क्लिक करके डाउनलोड करें। src\share\toolsअपने Cygwin होम डायरेक्टरी में hsdis डायरेक्टरी (पाया हुआ ) निकालें ।
  5. साइगविन टर्मिनल में, दर्ज करें cd ~/hsdis
  6. बनाने के लिए hsdis-amd64.dll, दर्ज करें

    make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    बनाने के लिए hsdis-i386.dll, दर्ज करें

    make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    या तो मामले में, 2.25आपके द्वारा डाउनलोड किए गए बिनुटिल संस्करण के साथ बदलें । OS=Linuxयह आवश्यक है, क्योंकि साइग्विन लिनक्स जैसा वातावरण है, लेकिन hsdis मेकफाइल इसे इस तरह से पहचानने में विफल रहता है।

  7. संदेशों के साथ बिल्ड विफल हो जाएगा ./chew: No such file or directoryऔर gcc: command not found। संपादित <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefileवर्डपैड या बदलने के लिए नोटपैड ++ की तरह एक पाठ संपादक में SUBDIRS = doc po(लाइन 342, अगर binutils 2.25 का प्रयोग करके) के लिए SUBDIRS = po। पिछली कमांड को फिर से चलाएं।

DLL को अब इसे अपने JRE या डायरेक्टरी से कॉपी करके hsdis\build\Linux-amd64या इंस्टॉल किया जा सकता है । आप अपने सिस्टम पर ऐसी सभी निर्देशिकाएं खोज सकते हैं ।hsdis\build\Linux-i586bin\serverbin\clientjava.dll

बोनस टिप: यदि आप एटी एंड टी के लिए इंटेल एएसएम सिंटैक्स पसंद करते हैं, -XX:PrintAssemblyOptions=intelतो आपके द्वारा उपयोग किए जाने वाले किसी भी अन्य PrintAssembly विकल्प के साथ निर्दिष्ट करें।

* पेज लाइसेंस क्रिएटिव कॉमन्स है


1
अन्य प्लेटफार्मों के लिए पूर्व-निर्मित बायनेरिज़ - kenai.com/projects/base-hsdis/downloads
अश्विन जयप्रकाश

@AshwinJayaprakash मैं मैक ओएस में इन फ़ाइलों को कहाँ रखने वाला हूँ?
कोरे तुगे

@ कोरेयुगे ने उन्हें/usr/lib/
जीन-फ्रांस्वा

मैंने लिंक-टू-पेज के नवीनतम संस्करण से कॉपी करके उत्तर को अपडेट किया है, लेकिन यह इस कारण को उजागर करता है कि हम आमतौर पर बाहरी संसाधनों को कॉपी करने के बजाय उन्हें शब्दशः कॉपी करते हैं।
अलेक्सांद्र डबिन्सकी

@AleksandrDubinsky अपडेट के लिए धन्यवाद। मैंने इसे इस उद्देश्य से कॉपी किया है: अगर उस साइट को नीचे लाया गया तो मेरा जवाब अभी भी आत्म निहित होगा ...
assylias

29

उपयोग करने के लिए आपको एक hsdis प्लगइन की आवश्यकता है PrintAssembly। एक सुविधाजनक विकल्प FCML लाइब्रेरी पर आधारित hsdis प्लगइन है।

इसे UNIX जैसी प्रणालियों के लिए संकलित किया जा सकता है और विंडोज पर आप स्रोत पर एफसीएमएल डाउनलोड अनुभाग में उपलब्ध पूर्व-निर्मित पुस्तकालयों का उपयोग कर सकते हैं :

विंडोज में स्थापित करने के लिए:

  • Dll निकालें (यह hsdis-1.1.2-win32-i386.zip और hsdis-1.1.2.2-win32-amd64.zip में पाया जा सकता है)।
  • जहाँ भी मौजूद है java.dll(विंडोज खोज का उपयोग करें) dll की प्रतिलिपि बनाएँ । अपने सिस्टम पर, मैंने इसे दो स्थानों पर पाया:
    • C:\Program Files\Java\jre1.8.0_45\bin\server
    • C:\Program Files\Java\jdk1.8.0_45\jre\bin\server

लिनक्स में स्थापित करने के लिए:

  • स्रोत कोड डाउनलोड करें, इसे निकालें
  • cd <source code dir>
  • ./configure && make && sudo make install
  • cd example/hsdis && make && sudo make install
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
  • मेरे सिस्टम पर, JDK अंदर है /usr/lib/jvm/java-8-oracle

इसे कैसे चलाएं:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code 
-jar fcml-test.jar

अतिरिक्त कॉन्फ़िगरेशन पैरामीटर:

कोड प्रिंट मशीन कोड mnemonic से पहले।
इंटेल इंटेल सिंटैक्स का उपयोग करें।
गैस एटी एंड टी कोडांतरक सिंटैक्स (जीएनयू कोडांतरक संगत) का उपयोग करें।
दिसम्बर प्रिंटों IMM और दशमलव मान के रूप में विस्थापन। निर्देश के mnemonic हिस्से के लिए
mpad = XX पैडिंग।
cpad = XX कोड मशीन कोड के लिए।
seg डिफ़ॉल्ट सेगमेंट रजिस्टर दिखाता है।
शून्य एचईएक्स शाब्दिक के मामले में अग्रणी शून्य दिखाओ।

विंडोज के मामले में इंटेल सिंटैक्स एक डिफ़ॉल्ट है, जबकि एटी एंड टी एक जीएनयू / लिनक्स के लिए एक डिफ़ॉल्ट है।

अधिक जानकारी के लिए FCML लाइब्रेरी रेफरेंस मैनुअल देखें


लिबर को ठीक करने के लिए धन्यवाद। यह लिनक्स पर भी बढ़िया काम कर रहा है। मैं अपनी पुरानी टिप्पणियों को अव्यवस्थित रखने के लिए हटा रहा हूं।
Aleksandr Dubinsky

लिनक्स पर, जब मैं libhsdis.so इंस्टॉल करता हूं और hsdis-amd64.so के लिए सॉफ्ट लिंक बनाता हूं, मैं जावा कमांड चलाता हूं, तो यह hsdis-amd64.so को ढूंढ नहीं सकता है। मैं रीबूट करता हूं और फिर ररव जावा, यह ठीक है। सॉफ्ट लिंक को तुरंत काम करने के लिए रिबूट से कैसे बचें? लॉग आउट?
gfan

2
बस थोड़ा सा जोड़: कुछ लिनक्स वितरण पर, आप सिर्फ एक पैकेज स्थापित कर सकते हैं, उदाहरण के लिए उबंटू में: apt-get install libhsdis0-fcml( askubuntu.com/a/991166/489909 )। इसे स्वयं बनाना आवश्यक नहीं हो सकता है।
डेविड जॉर्ज रेचल्ट

8

उत्पाद मोड में भी हॉटस्पॉट (सूर्य था) जेवीएम के लिए:

http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly

कुछ विधानसभा की आवश्यकता है: यह एक प्लगइन की जरूरत है।


ऐसा लगता है कि आपके उत्तर में लिंक चला गया है। क्या आप कृपया इसे अपडेट करेंगे? अग्रिम धन्यवाद।
चाजुन झोंग

5

मेरा मानना ​​है कि अगर आप इसे विंडोज़ मशीन पर चला रहे हैं तो WinDbg मददगार होगा। मैंने सिर्फ एक जार चलाया है।

  • फिर मैं विंडबग के माध्यम से जावा प्रक्रिया से जुड़ा
  • परीक्षित सूत्र ~ कमांड द्वारा ; 11 धागे थे, 0 धागा मुख्य कार्यकर्ता धागा था
  • 0-थ्रेड में परिवर्तित - ~ 0 s
  • केबी द्वारा मानव रहित कॉलस्टैक के माध्यम से देखा गया था:

    0008fba8 7c90e9c0 ntdll! KiFastSystemCallRet
    0008fbac 7c8025cb ntdll! ZwWaitForSingleObject + 0xc
    0008fc10 7c802532 kernel32! WaitForSingleObjectEx + 0xa8
    0008fc24 00403a13 kernel32! WaitForSingleObject + 0x12
    0008fc40 00402f68 जावा + 0x3a13
    0008fee4 004087b8 जावा + 0x2f68
    0008ffc0 7c816fd7 जावा + 0x87b8

    0008fff0 00000000 kernel32! BaseProcessStart + 0x23

हाइलाइट की गई लाइनें JVM पर डायरेक्ट JIT-ed कोड चला रही हैं।

  • तब हम विधि पते की तलाश कर सकते हैं:
    java + 0x2f68 00402f68 है

  • WinDBG पर:
    देखें पर क्लिक करें -> डिसएस्पेशन।
    Edit -> Address पर क्लिक करें। वहाँ 00402f68
    रखो और मिल गया

    00402f68 55 पुश
    ebp 00402f69 8bec mov ebp, esp
    00402f6b 81ec80020000 उप एस्प, 280h
    00402f71 53 पुश
    ईबेक्स 00402f72 56 पुश
    esi 00402f73 57 पुश एडी
    ... और इतने पर

अतिरिक्त जानकारी के लिए यहाँ उदाहरण है कि प्रक्रिया खोजकर्ता और WinDbg का उपयोग करके मेमोरी डंप से JIT-ed कोड को कैसे ट्रेस करें।


4

मशीन कोड और कुछ प्रदर्शन डेटा देखने का एक अन्य तरीका एएमडी के कोडअनलिस्ट या ओप्रोफाइल का उपयोग करना है, जिसमें जावा कोड को मशीन कोड के रूप में निष्पादित करने के लिए एक जावा प्लगइन है।


0

जेएमएच के परफ्यूम प्रोफाइलर्स ( LinuxPerfAsmProfilerया WinPerfAsmProfiler) के साथ अपने हॉटस्पॉट्स की असेंबली प्रिंट करें । जेएमएच को hsdisपुस्तकालय की आवश्यकता होती है क्योंकि यह निर्भर करता है PrintAssembly

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.