2010-10-28 2 views
14

में सिंक्रनाइज़ेशन के क्रम को अत्यधिक समवर्ती प्रणालियों में, यह विश्वास करना मुश्किल हो सकता है कि ताले का उपयोग सही है। विशेष रूप से, डेडलॉक्स का परिणाम हो सकता है यदि ताले किसी ऑर्डर में अधिग्रहित किए जाते हैं जिसे किसी अन्य थ्रेड में उचित क्रम में हासिल किए जाने की अपेक्षा नहीं की जाती थी।जावा

उपकरण (उदा। कवरिटी) हैं जो कोड आधार पर स्थिर विश्लेषण कर सकते हैं और "असामान्य" लॉकिंग ऑर्डर की तलाश कर सकते हैं। मैं अपनी जरूरतों को पूरा करने के लिए अन्य विकल्पों का पता लगाना चाहता हूं।

क्या जावा कोड के उपकरण के लिए कोई हल्का वजन * उपकरण है जो अपेक्षाओं के अलावा किसी अन्य क्रम में लॉक प्राप्त किए जा रहे मामलों का पता लगा सकता है? टिप्पणियों/टिप्पणियों के माध्यम से लॉकिंग ऑर्डर को स्पष्ट रूप से कॉल करने के साथ मैं ठीक हूं।

निशुल्क और/या ओपन-सोर्स समाधान पसंदीदा। अगर इस समस्या के लिए गैर-उपकरण दृष्टिकोण हैं तो कृपया टिप्पणी भी करें।

* मेरी प्रयोजनों, हल्के वजन का मतलब के लिए ...

  • यदि यह उपकरण है, मैं अभी भी अपने कार्यक्रम में एक ही बॉलपार्क प्रदर्शन के साथ चला सकते हैं। 30-50% गिरावट स्वीकार्य है, मुझे लगता है।
  • मुझे उपकरण से बातचीत करने के आधे दिन खर्च करने की ज़रूरत नहीं है, बस इसे "ठीक" निकालने के लिए। आदर्श रूप में मुझे केवल यह ध्यान देना चाहिए कि कोई समस्या होने पर मैं इसका उपयोग कर रहा हूं।
  • यदि यह उपकरण है, तो उत्पादन वातावरण के लिए इसे अक्षम करना आसान होना चाहिए।
  • यह हर synchronize कथन पर मेरे कोड को अव्यवस्थित नहीं करना चाहिए। जैसा कि पहले उल्लेख किया गया है, मैं ऑब्जेक्ट्स या ऑब्जेक्ट्स के वर्गों को स्पष्ट रूप से टिप्पणी/एनोटेट करने के साथ ठीक हूं, जो रिश्तेदार आदेशों से बंद हो जाते हैं।
+1

... यही कारण है कि अभिनेता मॉडल और एसटीएम अधिक से अधिक लोकप्रिय हो रहे हैं –

+0

किसी के पास java.lang.hread.holdsLock (ऑब्जेक्ट) का संदर्भ देने का उत्तर था जिसे तत्काल हटा दिया गया था। मैं उस विधि को अपने आप नहीं ढूंढ पाया, पॉइंटर के लिए धन्यवाद। मेरा सवाल अभी भी खड़ा है, यद्यपि। –

+0

क्या आपको ऐसा कुछ करने के लिए सभ्य कुछ मिला है? मेरे पास सी ++ में बहुत परिष्कृत डेडलॉक पहचान कोड है और मेरे मामले में मैं अपने जावा कोड को उन मामलों को पकड़ने के लिए करना चाहता हूं जहां सी ++ और/या जावा पक्ष पर ताले एक दूसरे के साथ हस्तक्षेप कर सकते हैं और परिणामस्वरूप डेडलॉक्स हो सकते हैं। – Pavel

उत्तर

3

मैंने AspectJ का उपयोग नहीं किया है, इसलिए इसका उपयोग नहीं करना चाहिए कि इसका उपयोग करना कितना आसान है। मैंने कस्टम कोड प्रोफाइलर बनाने के लिए ASM का उपयोग किया है, यह लगभग 2 दिन का काम था। उपकरण सिंक्रनाइज़ेशन का प्रयास समान होना चाहिए। पहलुओं के साथ तेजी से बढ़ने के बाद AspectJ तेज और आसान होना चाहिए।

मैंने हमारे सी ++ आधारित सर्वर के लिए डेडलॉक डिटेक्टिंग ट्रेस लागू किया है। यहाँ है कैसे मैंने किया:

  • जब कभी प्राप्त करने या एक ताला रिहा मैं पता लगाया:
    • <time> <tid> <lockid> <acquiring|releasing> <location in code>
  • इस अतिरिक्त ट्रेस प्रभावित प्रदर्शन काफी तेजी से और उत्पादन में प्रयोग करने योग्य नहीं था।
  • तो जब उत्पादन में एक संभावित डेडलॉक की खोज हुई तो मैंने लॉग फ़ाइल का उपयोग यह पता लगाने के लिए किया कि डेडलॉक के आसपास क्या हो रहा था। फिर मेरे ट्रेसिंग चालू होने के साथ एक परीक्षण वातावरण में इस कार्यक्षमता को पुन: उत्पन्न किया।
  • फिर मैंने लॉग फ़ाइल पर एक स्क्रिप्ट चलाई यह देखने के लिए कि क्या डेडलॉक संभव था और कैसे।मैं एक awk स्क्रिप्ट का इस्तेमाल किया, इस एल्गोरिथ्म का उपयोग कर:
    • Foreach लाइन
      • यदि प्राप्त
        • इस सूत्र
        • के लिए मौजूदा ताले की सूची में lockid जोड़ने एक सेट के लिए इस सूची में ताले की एक जोड़ी जोड़ने इस धागे के लिए जोड़े को लॉक करें। Lock A -> Lock B -> Lock C की सूची के लिए उदाहरण के लिए जोड़े (Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
        • वर्तमान lockid सूची की पूंछ से इस सूत्र
    • के लिए के लिए अन्य सभी थ्रेड को प्रत्येक ताला जोड़ी खोज के लिए जारी करता है, तो उत्पन्न रिवर्स लॉक जोड़े, प्रत्येक मैच एक संभावित डेडलॉक है इसलिए
    • प्रभावित एल्गोरिदम को बेहतर बनाने के बजाय जोड़े और थ्रेड मुद्रित करें, फिर डेस्क ने उस जांच की ई लॉक अधिग्रहण यह देखने के लिए कि क्या यह वास्तविक डेडलॉक था।

मैं दिनों की संख्या के लिए एक गतिरोध के कारणों का पता करने में नाकाम रहने के बाद ऐसा किया, यह कुछ और दिन लग गए लागू करने के लिए और कुछ ही घंटों गतिरोध को खोजने के लिए।

आप जावा बातों में इस दृष्टिकोण पर विचार करने के विचार कर रहे हैं कर रहे हैं:

  • आप केवल synchronized का उपयोग करते हैं अपने महत्वपूर्ण वर्गों की सुरक्षा के लिए? क्या आप java.lang.concurrent में कक्षाओं का उपयोग कर रहे हैं? (इन्हें विशेष हैंडलिंग/वाद्ययंत्र की आवश्यकता हो सकती है)
  • पहलुओं/एएसएम के साथ कोड स्थान मुद्रित करना कितना आसान है? मैंने सी ++ में __FILE__ और __LINE__ का उपयोग किया। एएसएम आपको कक्षा का नाम, विधि का नाम और हस्ताक्षर देगा।
  • आप अपने ट्रेसिंग/लॉगिंग की सुरक्षा के लिए उपयोग किए गए ताले का उपयोग नहीं कर सकते हैं।
  • यदि आप फ़ाइल ऑब्जेक्ट के लिए प्रति थ्रेड और थ्रेड स्थानीय संग्रहण का उपयोग करते हैं तो आप अपने उपकरण को व्यवस्थित कर सकते हैं।
  • आप उन वस्तुओं की विशिष्ट पहचान कैसे करते हैं जिन्हें आप सिंक्रनाइज़ करते हैं? हो सकता है कि ToString() और System.identityHashCode() पर्याप्त होगा, लेकिन अधिक आवश्यकता हो सकती है। मैंने सी ++ में ऑब्जेक्ट का पता इस्तेमाल किया।
+0

यह एक उचित समाधान है, लेकिन मैं उम्मीद कर रहा था कि एक उपकरण था जो मेरे लिए यह सब काम करेगा। एएसएम को और अधिक देखने के लिए जा रहे हैं - धन्यवाद। –

0

तुम वहाँ सभी तरह मिलता नहीं है, लेकिन एक अच्छी शुरुआत JCIP annotations उपयोग करने के लिए है, और FindBugs कुछ चीजें फैल जाती है।

+0

जब तक मुझे कुछ याद नहीं आ रहा है, तो FindBugs में मॉनिटर (सिंक्रनाइज़ किए गए ब्लॉक) ऑर्डर करने के लिए कोई चेक नहीं है। –

+0

@ डेरिक चावल: मुझे किसी भी उपकरण से अवगत नहीं था जो ओक्यू पूछ रहा था, लेकिन आसपास के क्षेत्र में कुछ प्रदान किया ... – andersoj

1

आप AspectJ का उपयोग कर सकते हैं, जो सीखने के लिए अपेक्षाकृत आसान है और आप अपने धागे और किसी भी ताले की निगरानी के अपने स्वयं के अनुकूलित और सरलीकृत तरीके को सेट करने की अनुमति देंगे।

+1

धन्यवाद। जब तक मैं इस पत्र में नहीं आया, तब तक मैंने इस विचार का पालन किया, "एस्पेक्टजे में सिंक्रनाइज़ ब्लॉक के लिए एक जॉइंट प्वाइंट": http://www.cs.man.ac.uk/~xic/SBJP_AspectJ.pdf –

+0

अच्छा पेपर। लिंक साझा करने के लिए धन्यवाद, और खेद है कि नुकसान आपके परिस्थिति में उपयोग करने योग्य नहीं हैं। –