2011-10-28 18 views
7

मैं एक जेवीएम दुर्घटना की जांच कर रहा हूं जो कभी-कभी मेरे आवेदन में होता है। Hs_err फ़ाइल में क्रैश के बारे में निम्न विवरण शामिल हैं।बफरब्लोब :: JVM क्रैश लॉग में इंटरप्रेटर का क्या अर्थ है?

# SIGSEGV (0xb) at pc=0x065e68f4, pid=20208, tid=570166160 
# 
# Java VM: Java HotSpot(TM) Server VM (10.0-b23 mixed mode linux-x86) 

...

# Problematic frame: 
# V [libjvm.so+0x5e68f4] 

...

Current thread (0x099ea800): JavaThread "Thread-315" daemon [_thread_in_vm, id=25782, stack(0x21fa3000,0x21fc1000)] 

...

vm_info: Java HotSpot(TM) Server VM (10.0-b23) for linux-x86 JRE (1.6.0_07-b06), built on Jun 10 2008 01:20:15 by "java_re" with gcc 3.2.1-7a (J2SE release) 

तो यह मुझसे कहता है कि JVM एक segfault मारा जब कुछ चल रहा है जावा कोड त्रुटि लॉग में धागे के ढेर के बारे में जानकारी भी शामिल है जो क्रैश हो गई है।

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
V [libjvm.so+0x5e68f4] 
V [libjvm.so+0x1c054f] 
V [libjvm.so+0x1bfef2] 
V [libjvm.so+0x1bf57f] 
V [libjvm.so+0x592495] 
V [libjvm.so+0x365c4e] 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
v ~BufferBlob::Interpreter 
J org.myapp.AppClass.getBytes()Lorg/myapp/ByteHolder; 

मैं दुर्घटना से कोर फ़ाइल से कनेक्ट और ढेर के बारे में अधिक विवरण प्राप्त करने के GDB इस्तेमाल किया है। यह मुझे निम्नलिखित आउटपुट देता है।

#5 <signal handler called> 
#6 0x065e68f4 in interpretedVFrame::monitors() const() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#7 0x061c054f in get_or_compute_monitor_info(JavaThread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#8 0x061bfef2 in revoke_bias(oopDesc*, bool, bool, JavaThread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#9 0x061bf57f in BiasedLocking::revoke_and_rebias(Handle, bool, Thread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#10 0x06592495 in ObjectSynchronizer::fast_enter(Handle, BasicLock*, bool, Thread*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 
#11 0x06365c4e in InterpreterRuntime::monitorenter(JavaThread*, BasicObjectLock*)() 
    from /usr/java/jdk1.6.0_07/jre/lib/i386/server/libjvm.so 

यह दिखाता है कि छह libjvm.so मूल बग रिपोर्ट में सूचीबद्ध फ्रेम एक जावा ताला हथियाने से संबंधित थे। हालांकि, मुझे org.myapp.AppClass.getBytes() के भीतर कोई कोड नहीं मिल रहा है जो किसी भी ताले का उपयोग करता है।

बफरब्लोब :: स्टैक्स में इंटरप्रेटर लाइनों का क्या अर्थ है? क्या ये जावा स्टैक फ्रेम हैं? जेवीएम ढेर फ्रेम? क्या इन स्टैक फ्रेम में क्या कहा जा रहा है यह काम करना संभव है?

नोट: कृपया यह सुझाव न दें कि मैं एक नए हॉटस्पॉट JVM पर स्विच करने का प्रयास करता हूं। मैं सीएमएस कलेक्टर पर भरोसा करता हूं और हाल ही में वी 1.6 हॉटस्पॉट जेवीएम में से कोई भी सीएमएस कलेक्टर के साथ पर्याप्त स्थिर नहीं है।

संपादित करें: यह दस्तावेज़ (http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf) कहता है कि "वी" फ्रेम एक "वीएम जेनरेट स्टब फ्रेम" है। कोई विचार क्या इसका मतलब है?

EDIT2: org.myapp.AppClass.getBytes() DataInputStream से पढ़ता है। इसमें निम्नलिखित स्टैक ट्रेस शामिल हो सकते हैं:

AppClass.getBytes() 
AppClass.readByte() 
DataInputStream.readByte() 
SocketInputStream.read() 
SocketInputStream.read(byte[],int,int) 
PlainSocketImpl.aquireFD() 

यह अंतिम विधि लॉक पकड़ती है। यह ऊपर सूचीबद्ध जेवीएम कोड में अंतिम कॉल का स्रोत हो सकता है। उपरोक्त इस ढेर में साफ सुविधा है कि GetBytes() के नीचे 5 जावा स्टैक फ्रेम हैं। यह "जावा फ्रेम" की सूची में बफरब्लोब :: इंटरप्रेटर की 5 लाइनों के साथ अच्छी तरह मेल खाता है।

इस नए सवालों के एक जोड़े को जन्म देती है:

  • क्या यह संभव है कि "मूल फ्रेम" के तहत खंड सिर्फ "जावा फ्रेम के तहत उसी तर्ज के डुप्लिकेट BufferBlob :: दुभाषिया के 5 लाइनों " अनुभाग?
  • त्रुटि लॉग इन 5 स्टैक फ्रेम के विवरण क्यों नहीं दिखाता है? -

EDIT3 यह ओरेकल बग एक ही/समान बग होने की संभावना दिखाई देती है: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676175

ढेर दिखाया ट्रेस समान नहीं है, लेकिन यह revoke_and_rebias जो 6u14 में तय किया गया था में एक दुर्लभ रेस स्थिति का उल्लेख है।

EDIT4 - इनाम संदेश कहना चाहिए "हॉटस्पॉट कार्यान्वयन से परिचित"

उत्तर

4

VM generated stub frame सिर्फ मतलब है कि कोड है कि निष्पादित हो रहा है JVM द्वारा तैयार की गई है।

स्टैक स्वयं (जीडीबी से) दिखाता है कि वीएम एक सुरक्षित बिंदु तक पहुंचने का प्रयास कर रहा है क्योंकि यह पक्षपातपूर्ण ताला रद्द कर रहा है। आप this blog में पूर्वाग्रह लॉकिंग के बारे में पढ़ सकते हैं। इसका मतलब है कि कुछ धागे ने एक मॉनीटर हासिल किया है जो कि उस धागे की तरफ निगरानी करने वाले पक्षपात करता है। बाद में कुछ अन्य थ्रेड लॉक चाहता है, इसलिए इसे पूर्वाग्रह को निरस्त करना होगा जिसके लिए एक सुरक्षित बिंदु तक पहुंचने की आवश्यकता है (यानी कोई धागा बाइट कोड उर्फ ​​को निष्पादित नहीं कर रहा है)।

आपकी त्रुटि कुछ विधियों के deoptimisation के दौरान JVM क्रैशिंग का संकेत भी हो सकती है। इसका अर्थ यह है कि JVM ने पहले से ही कुछ विधियों को अनुकूलित (संकलित) किया है, लेकिन उसके बाद एक कोड पथ मारा है जिससे इसे हटाने की आवश्यकता होती है क्योंकि संकलित विधि अब मान्य नहीं है। JVM अपग्रेड के बिना आप इसके लिए कोई फिक्स ढूंढने की संभावना नहीं है।

ऐसा लगता है कि 2 समाधान है आप,

  1. की कोशिश करना चाहते हो सकता है अगर यह पक्षपातपूर्ण लॉकिंग से प्रेरित है इसे बंद (-XX:-UseBiasedLocking)
  2. अगर यह deoptimisation से प्रेरित है, हमलावर विधि खोजने के लिए और बता हॉटस्पॉट इसे पहले स्थान पर संकलित नहीं करने के लिए, this link

दोनों दृष्टिकोणों पर प्रदर्शन प्रभाव पड़ सकता है।

एनबी यह कम निराशाजनक होगा यदि आप परीक्षण परिदृश्य को काम कर सकते हैं जो विश्वसनीय रूप से समस्या को पुन: उत्पन्न करता है।

+0

"इसका मतलब है कि कोड है कि क्रियान्वित JVM द्वारा तैयार की गई है, यानी संकलित (अनुकूलित) कोड" - JVM नाम "org.myapp.AppClass.getBytes()" का प्रबंधन के बावजूद यह किया जा रहा है एक संकलित विधि (टैग "जे" के अनुसार)। क्या JVM कभी-कभी विधि को निष्पादित करने में असमर्थ है? या "बफरब्लोब :: इंटरप्रेटर" लाइनें अंतर्निहित काम के बिट्स का संदर्भ देती हैं जो जेवीएम ने मेरे प्रोग्राम में डाला है? – mchr

+1

मैंने उस बिट को संपादित किया क्योंकि यह मेरा कहना नहीं था। जहां तक ​​मुझे पता है कि एक साधारण संकलित विधि अभी भी एक जे के रूप में दिखाई देती है। इंटरप्रेटर लाइनें जेवीएम द्वारा बनाए गए कोड को संदर्भित करती हैं। JVM कई चीजें करता है (जीसी, अनुकूलन) अन्य आपके कोड को चलाते हैं। – Matt

+0

हम्म जो समझ में आता है सिवाय इसके कि मैं काफी हद तक निश्चित हूं कि स्टैक में मेरी विधि (org.myapp.AppClass.getBytes()) कोई लॉकिंग नहीं करती है। यही कारण है कि मैं बफरब्लोब :: इंटरप्रेटर लाइनों को और विधि कॉल का प्रतिनिधित्व करना चाहता था। क्या यह संभव है? मैंने सोचा कि जीसी और जेआईटी अपने धागे में हुआ था। – mchr

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