2010-08-11 20 views
9

एक एप्लिकेशन जिसे हमने हाल ही में "java.lang.OutOfMemoryError" के बारे में एक संदेश के साथ दुर्घटनाग्रस्त रूप से क्रैश करना शुरू कर दिया है: चंक :: नया के लिए 858 9934608 बाइट्स का अनुरोध किया। स्वैप स्पेस से बाहर? "।जावा जेआईटी कंपाइलर आउटऑफमेमरी एरर

मैं नेट पर चारों ओर देखा है, और हर जगह सुझाव

  • तक ही सीमित हैं स्मृति सेटिंग्स के साथ जावा
  • बेला के पिछले संस्करण पर वापस सर्वर मोड
  • के बजाय
  • उपयोग ग्राहक

पिछले संस्करण पर वापस जाने का तात्पर्य है कि नए जावा में एक बग है, लेकिन मैंने इसका कोई संकेत नहीं देखा है। स्मृति बिल्कुल कोई मुद्दा नहीं है; सर्वर में 32 जीबी उपलब्ध है, और एक्सएमएक्स 20 पर सेट है जबकि एक्सएमएस 10 है। मैं शेष 12 जीबी से बाहर चलने वाले जेवीएम को नहीं देख सकता (मशीन पर अन्य प्रक्रियाओं के मुकाबले कम राशि)। और हम एप्लिकेशन और पर्यावरण की प्रकृति के कारण सर्वर मोड से फंस गए हैं।

जब मैं एप्लिकेशन के लिए मेमोरी और सीपीयू उपयोग को देखता हूं, तो मुझे पूरे दिन लगातार स्मृति उपयोग दिखाई देता है, लेकिन फिर अचानक मरने से ठीक पहले CPU उपयोग 100% तक चला जाता है और स्मृति उपयोग एक्स से जाता है, एक्स + 2 जीबी, एक्स + 4 जीबी, (कभी-कभी) एक्स + 8 जीबी, जेवीएम मौत के लिए। ऐसा लगता है कि जेआईटी संकलन में दोहराए गए सरणी आकार बदलने का चक्र हो सकता है।

मैंने अब ऊपर 8 जीबी अनुरोध और 16 जीबी अनुरोधों के साथ त्रुटि देखी है। हर बार, यह घटित होने पर विधि संकलित की जाती है। यह एक साधारण विधि है जिसमें गैर-नेस्टेड लूप, कोई रिकर्सन नहीं है, और ऑब्जेक्ट्स पर विधियों का उपयोग करता है जो स्थिर सदस्य फ़ील्ड या इंस्टेंस सदस्य फ़ील्ड को कम गणना के साथ सीधे लौटाते हैं।

  1. किसी को भी किसी भी सुझाव हैं:

    तो मैं 2 प्रश्न हैं?

  2. क्या मैं परीक्षण कर सकता हूं कि परीक्षण प्रक्रिया पर इस विशिष्ट विधि को संकलित करने में कोई समस्या है, पूरे एप्लिकेशन को चलाने के बिना, सीधे जेआईटी कंपाइलर का आह्वान करते हुए? या क्या मुझे एप्लिकेशन शुरू करना चाहिए और इसे बहुत छोटी कॉल गिनती (जैसे 2) के बाद विधियों को संकलित करने के लिए कहा जाना चाहिए ताकि इसे दिन में एक यादृच्छिक बिंदु के बजाय लगभग तुरंत संकलित करने के लिए मजबूर किया जा सके?

@StephenC

JVM 1.6.0_20 (पहले 1.6.0_0), सोलारिस पर चल रहा है। मुझे पता है कि यह संकलन है जो कुछ कारणों से समस्या पैदा कर रहा है।

  1. सेकंड के उस तक पहुंचने में ps से पता चलता आईडी (jstack से) संकलक धागा करने के लिए इसी के साथ एक जावा धागा CPU समय
  2. jstack की 100% अप ले जा रहा है पता चलता है कि इस मुद्दे को JavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]
  3. में है

jstack में उल्लिखित विधि हमेशा एक ही है, और हमने लिखा है। यदि आप नमूना jstack आउटपुट देखते हैं तो आपको पता चलेगा कि मेरा क्या मतलब है, लेकिन स्पष्ट कारणों से मैं कोड नमूने या फ़ाइल नाम प्रदान नहीं कर सकता। मैं कहूंगा कि यह एक बहुत ही सरल विधि है। Essentiall कुछ हद तक शून्य जांच, 2 लूप के लिए जो समानता जांच करता है और संभवतः मान असाइन करता है, और कुछ सरल विधि बाद में कॉल करता है।सभी कोड की 40 लाइनों में सभी।

यह समस्या 2 सप्ताह में 2 बार हुई है, हालांकि एप्लिकेशन हर दिन चलता है और दैनिक पुनरारंभ होता है। इसके अलावा, आवेदन इनमें से किसी भी समय भारी भार के तहत नहीं था।

+0

यह उपयोगी होगा अगर आपने कहा कि आप जो जेवीएम संस्करण और पैच स्तर का उपयोग कर रहे हैं (और यह पहले क्या था) और आपका ओएस/हार्डवेयर प्लेटफार्म क्या है। साथ ही, आपने यह निष्कर्ष निकाला है कि समस्या जेआईटी संकलन के दौरान हो रही है, आपने जिस तरीके को संकलित किया है, उसे समझ लिया है ... और विधि का कोड कैसा दिखता है। –

+0

क्या आपको एक संतोषजनक समाधान मिला? –

+0

* बहुत * देर से उत्तर के लिए खेद है - मैंने जवाब अब ध्वजांकित किया है – Phil

उत्तर

1

ठीक है, मैंने एक त्वरित खोज की और सूर्य जावा forums that discusses पर एक धागा पाया। आशा करता हूँ की ये काम करेगा।

+0

हाँ, मैंने यह भी देखा। उनका मुद्दा एक ही आवंटन पर शेष स्मृति के आगे चलने के साथ है। मैं कई सरणी resizings देख रहा हूँ जहां कोई भी नहीं होना चाहिए। ऐसा कोई कारण नहीं है कि किसी विधि को संकलित करने के लिए 16 जीबी मेमोरी की आवश्यकता हो, है ना? – Phil

+0

फिर आपने शायद आपके प्रश्न में उल्लिखित सुझावों का भी प्रयास किया है। क्या उनमें से कोई काम था? – naikus

1

यहां एक और entry on Oracles forum। समान स्पोराडिक दुर्घटना। एक जवाब है जहां जीसी के उत्तरजीवी अनुपात को पुन: कॉन्फ़िगर करके समस्या हल हो गई है।

5

आप .hotspot_compiler नामक फ़ाइल बनाकर और इसे अपने एप्लिकेशन की कार्यशील निर्देशिका में डालकर JIT'ed होने से किसी विशेष विधि को बहिष्कृत कर सकते हैं। सीधे शब्दों में निम्न स्वरूप में फ़ाइल में एक प्रविष्टि जोड़ें:

exclude com/amir/SomeClass someMethod 

और संकलक से सांत्वना उत्पादन तरह दिखेगा:

### Excluding compile: com.amir.SomeClasst::someMethod 

अधिक जानकारी के लिए this पढ़ें। यदि आप सुनिश्चित नहीं हैं कि आप 'वर्किंग डायरेक्टरी' एप्लिकेशन क्या हैं, तो

-XX:CompileCommandFile=/my/excludefile/location/.hotspot_compiler 

अपनी जावा स्टार्ट स्क्रिप्ट या कमांड लाइन में उपयोग करें।

वैकल्पिक रूप से, यदि आप सुनिश्चित नहीं हैं कि यह JIT कंपाइलर्स गलती है, और यह देखना चाहते हैं कि आप बिना किसी JIT'ing के समस्या को पुन: उत्पन्न कर सकते हैं, तो अपनी जावा प्रक्रिया -Xint के साथ चलाएं।

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