2011-08-15 11 views
18

मुझे टॉमकैट 6 (जावा 1.6.0_22, लिनक्स) पर चल रहे स्प्रिंग एमवीसी वेब एप्लिकेशन के लिए जेस्टैक से मिले थ्रेड डंप को समझने में कठिनाइयां हो रही हैं। ।जावा थ्रेड डंप: "लॉक करने का इंतजार" के बिना ब्लॉक्ड थ्रेड ...

मैं धागे को अवरुद्ध करता हूं (जो अन्य थ्रेडों को प्रतीक्षा करने का कारण बनता है) जो खुद को अवरुद्ध कर रहे हैं, हालांकि थ्रेड डंप मुझे नहीं बताता है कि वे किस मॉनिटर के लिए प्रतीक्षा कर रहे हैं।

उदाहरण:

"TP-Processor75" daemon prio=10 tid=0x00007f3e88448800 nid=0x56f5 waiting for monitor entry [0x00000000472bc000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
     at java.lang.Class.initAnnotationsIfNecessary(Class.java:3067) 
     - locked <0x00007f3e9a0b3830> (a java.lang.Class for org.catapultframework.resource.ResourceObject) 
     at java.lang.Class.getAnnotation(Class.java:3029) 
     ... 

अर्थात मुझे स्टैक ट्रेस में "लॉक करने की प्रतीक्षा ..." लाइन गुम है। स्पष्ट रूप से थ्रेड क्लास ऑब्जेक्ट को लॉक करता है, लेकिन मुझे नहीं लगता कि थ्रेड स्वयं अवरुद्ध क्यों है।

थ्रेड-डंप में डेडलॉक्स के लिए कोई संकेत नहीं है।

लॉकिंग मॉनीटर की पहचान करने के लिए मैं क्या कर सकता हूं?

धन्यवाद, ओलिवर

+0

क्या आप संदर्भ 0x00000000472bc000 के लिए कोई अन्य प्रविष्टियां देखते हैं? –

+0

नहीं, एक ही डंप में नहीं। 0x00000000472bc000 थ्रेड "टीपी-प्रोसेसर 75" की पहचान करता है, तो क्या आप डंप के भीतर एक ही थ्रेड के एकाधिक उल्लेखों की अपेक्षा करते हैं? – Oliver

+0

अच्छी तरह से 0x00000000472bc000 मॉनिटर को इंगित करता है कि थ्रेड प्रवेश करने का इंतजार कर रहा है। यह एक और थ्रेड मॉनिटर संदर्भ 0x00000000472bc000 में प्रवेश कर चुका है और टीपी-प्रोसेसर 75 वर्तमान में 0x00000000472bc000 जारी करने के लिए होल्डिंग थ्रेड का इंतजार कर रहा है –

उत्तर

10

जाहिर स्थिति है जहाँ हमने देखा अवरुद्ध धागे की इन प्रकार के भारी स्मृति की खपत और इसलिए बड़े पैमाने पर कचरा संग्रहण से संबंधित थे।

यह प्रश्न Java blocking issue: Why would JVM block threads in many different classes/methods? इसी तरह की स्थिति का वर्णन करता है, इसलिए मेरा मानना ​​है कि इन धागे को कचरा कलेक्टर द्वारा अवरुद्ध कर दिया गया था।

(वैसे भी, स्मृति मुद्दे को हल करने के बाद अवरुद्ध धागे के साथ इस समस्या चला गया था।)

2

मैं एक ऐसी ही समस्या अभी गूगल क्रोम में एक एप्लेट का उपयोग कर किया था।

संक्षेप में:

  • अवरोधित धागे अवरुद्ध किया जा सकता जब वी एम एक वर्ग को लोड करने की जरूरत है।
  • जब कक्षा को लोड करने की प्रक्रिया पूरी तरह से कुछ ऐप के लिए फ्रीज हो सकती है।

विस्तार में:

  1. मैं = एकल वर्ग फ़ाइलों के लिए फ़ोल्डर (कोई जार)
  2. codebase के साथ क्रोम में एक एप्लेट उपयोग कर रहा हूँ:

    मैं इस परिदृश्य पर था वेबसाइट लाइवकनेक्ट

  3. का उपयोग कर एप्लेट में फोकस-ईवेंट पास करती है आने वाली जेएस-कॉल Executornew Runnable() ... के साथ new Runnable() ... का उपयोग कर रही हैं प्रतीक्षा समय को कम करने के लिए कॉल को टैच करें और इस प्रकार जेएस में लटका है।
  4. यही वह समस्या है जहां समस्या आई!

स्पष्टीकरण:

  • new Runnable() एक annonymous भीतरी वर्ग जो लोड नहीं होने से पहले जे एस कॉल हुआ है।
  • इसलिए जेएस कॉल क्लास लोड को ट्रिगर करता है।
  • लेकिन अब क्लास लोडर अवरुद्ध है क्योंकि इसे आने वाली जेएस कॉल को संसाधित करने वाली एक ही कतार या तंत्र के माध्यम से ब्राउज़र (मैं अनुमान लगा रहा हूं) से बात करने की आवश्यकता है। ->waitForMessage()

    "Thread-20" daemon prio=4 tid=0x052e8400 nid=0x4608 in Object.wait() [0x0975d000] 
        java.lang.Thread.State: WAITING (on object monitor) 
        at java.lang.Object.wait(Native Method) 
        at sun.plugin2.message.Queue.waitForMessage(Unknown Source) 
        - locked <0x29fbc5d8> (a sun.plugin2.message.Queue) 
        at sun.plugin2.message.Pipe$2.run(Unknown Source) 
        at com.sun.deploy.util.Waiter$1.wait(Unknown Source) 
        at com.sun.deploy.util.Waiter.runAndWait(Unknown Source) 
        at sun.plugin2.message.Pipe.receive(Unknown Source) 
        at sun.plugin2.main.client.MessagePassingExecutionContext.doCookieOp(Unknown Source) 
        at sun.plugin2.main.client.MessagePassingExecutionContext.getCookie(Unknown Source) 
        at sun.plugin2.main.client.PluginCookieSelector.getCookieFromBrowser(Unknown Source) 
        at com.sun.deploy.net.cookie.DeployCookieSelector.getCookieInfo(Unknown Source) 
        at com.sun.deploy.net.cookie.DeployCookieSelector.get(Unknown Source) 
        - locked <0x298da868> (a sun.plugin2.main.client.PluginCookieSelector) 
        at sun.net.www.protocol.http.HttpURLConnection.setCookieHeader(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) 
        - locked <0x2457cdc0> (a sun.net.www.protocol.http.HttpURLConnection) 
        at com.sun.deploy.net.HttpUtils.followRedirects(Unknown Source) 
        at com.sun.deploy.net.BasicHttpRequest.doRequest(Unknown Source) 
        at com.sun.deploy.net.BasicHttpRequest.doGetRequestEX(Unknown Source) 
        at com.sun.deploy.cache.ResourceProviderImpl.checkUpdateAvailable(Unknown Source) 
        at com.sun.deploy.cache.ResourceProviderImpl.isUpdateAvailable(Unknown Source) 
        at com.sun.deploy.cache.DeployCacheHandler.get(Unknown Source) 
        - locked <0x245727a0> (a java.lang.Object) 
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) 
        - locked <0x24572020> (a sun.net.www.protocol.http.HttpURLConnection) 
        at java.net.HttpURLConnection.getResponseCode(Unknown Source) 
        at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source) 
        at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source) 
        at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source) 
        at java.security.AccessController.doPrivileged(Native Method) 
        at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source) 
        at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source) 
        at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source) 
        - locked <0x299726b8> (a sun.plugin2.applet.Applet2ClassLoader) 
        at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source) 
        - locked <0x299726b8> (a sun.plugin2.applet.Applet2ClassLoader) 
        at java.lang.ClassLoader.loadClass(Unknown Source) 
    

    आप इसे एक संदेश के लिए प्रतीक्षा कर रहा है देख सकते हैं:

यहां अवरोधित धागा उस वर्ग लोड करने की कोशिश कर रहा है।

"Applet 1 LiveConnect Worker Thread" prio=4 tid=0x05231800 nid=0x1278 waiting for monitor entry [0x0770e000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at MyClass.myMethod(MyClass.java:23) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.plugin.javascript.Trampoline.invoke(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source) 
    at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source) 
    at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source) 
    at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source) 
    at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source) 
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source) 
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source) 
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 

अतिरिक्त अन्य थ्रेड एक ही तरीके से अवरुद्ध गया:

एक ही समय है हमारे भेजे जे एस कॉल यहाँ अवरुद्ध किया जा रहा पर

। मुझे लगता है कि बाद के सभी वर्ग-लोड अनुरोधों को पहले अवरुद्ध वर्ग-लोडिंग थ्रेड द्वारा अवरोधित किया गया था।

जैसा कि पहले उल्लेख किया है, मेरा अनुमान है कि वर्ग लोडिंग प्रक्रिया लंबित जे एस कॉल है, जो अपने आप में लापता वर्ग द्वारा अवरुद्ध है लोड करने के लिए द्वारा अवरुद्ध है है।

समाधान:

  1. उत्प्रेरक किसी भी कॉल से पहले एप्लेट के निर्माता में सभी प्रासंगिक वर्गों लोड हो रहा है जे एस से बनाया जा सकता।
  2. यह मदद कर सकता है अगर कक्षा-फ़ाइलों को अलग-अलग लोड नहीं किया जा रहा है, लेकिन एक जार-फ़ाइल से। इस के पीछे सिद्धांत है: वर्ग लोडर सभी आने वाली जे एस कॉल रैप करने के लिए जार-फ़ाइल से वर्गों (जिसके साथ 1 .: उपयोग एक गतिशील Proxy वर्ग
  3. संयोजन में होगा लोड करने के लिए ब्राउज़र से बात करने की जरूरत नहीं है और उन्हें स्वतंत्र रूप से # 3 के लिए चलाने के एक Executor में

मेरे कार्यान्वयन:

public class MyClass implements JsCallInterface 
{ 

    private final JsCallInterface jsProxy; 

    private final static interface JsCallInterface 
    { 
     public void myMethod1Intern(String param1, String param2); 
    } 

    private final class JsCallRunnable implements Runnable 
    { 

     private final Method method; 
     private final Object[] args; 

     private JsCallRunnable(Method method, Object[] args) 
     { 
      this.method = method; 
      this.args = args; 
     } 

     public void run() 
     { 
      try 
      { 
       method.invoke(MyClass.this, args); 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public MyClass() 
    { 
     MyUtilsClass.class.getName(); // load class 
     JsCallRunnable.class.getName(); // load class 
     InvocationHandler jsCallHandler = new InvocationHandler() 
     { 

      public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable 
      { 
       MyUtilsClass.executeInExecutor(new JsCallRunnable(method, args)); 
       return null; 
      } 

     }; 
     jsProxy = (JsCallInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class<?>[] { JsCallInterface.class }, jsCallHandler); 
    } 

    public void myMethod1(String param1, String param2) 
    { 
     jsProxy.myMethod1Intern(param1, param2); 
     // needs to be named differently than the external method or else the proxy will call this method recursively 
     // alternatively the target-class in "method.invoke(MyClass.this, args);" could be a different instance of JsCallInterface 
    } 

    public void myMethod1Intern(String param1, String param2) 
    { 
     // do actual work here 
    } 
} 
0

यह Oracle के हॉटस्पॉट JVM में एक कॉस्मेटिक बग है - अपने स्टैक ट्रेस में जहां - locked <0x00007f3e9a0b3830> देखें कि यह वास्तव में - waiting to lock <0x00007f3e9a0b3830> कहना चाहिए।

अधिक जानकारी के लिए

this bug देखें।

3

चेक finalizer धागा अवरुद्ध या इंतजार कर रहा है।

एक जीसी स्वीप के दौरान, जीसी अपनी सफाई प्रदर्शन करने के लिए "दुनिया रोक" होगा। "दुनिया" की परिभाषा कचरा कलेक्टर का उपयोग और संदर्भ पर निर्भर करती है। यह धागे या उनमें से सभी का एक छोटा समूह हो सकता है। आधिकारिक तौर पर कचरा इकट्ठा करने से पहले, जीसी ऑब्जेक्ट के अंतिम() को आमंत्रित करेगा।

आप अवांछनीय स्थिति जहां finalizer तरीकों कार्यान्वित कर रहे हैं में हैं, तो अंतिम रूप दिए जाने कोड परिष्करण होने से रोक रहा हो सकता है और 'दुनिया' बंद कर दिया रहता है।

इस सबसे स्पष्ट जब धागे जा रहा है किसी अज्ञात जादू बल द्वारा स्थायी रूप से अवरुद्ध के बहुत सारे देखकर है: कोड को फिर से देखें जहां अवरुद्ध होता है और यह कोई मतलब नहीं कर देगा; इसके पास कहीं भी कोई अवरोधक कोड नहीं है और डंप यह नहीं बताएंगे कि यह किस मॉनिटर पर इंतजार कर रहा है क्योंकि कोई भी नहीं है। जीसी ने धागे को रोक दिया है।

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