2010-01-24 12 views
55

मैं एक प्रोग्राम चला रहा हूं जिसे मैंने जावा में ग्रहण में लिखा है। बहुत बड़े इनपुट के लिए कार्यक्रम में रिकर्सन का बहुत गहरा स्तर है। छोटे आदानों के लिए कार्यक्रम तथापि ठीक चलता है जब बड़े आदानों दिया जाता है, मैं निम्नलिखित त्रुटि मिलती है: जावा ढेर आकार बढ़ाकरजावा स्टैक ओवरफ़्लो त्रुटि - ग्रहण में स्टैक आकार को कैसे बढ़ाया जाए?

Exception in thread "main" java.lang.StackOverflowError 

इस हल किया जा सकता है और यदि ऐसा है तो, मैं कैसे ग्रहण में यह क्या करते हो?

अद्यतन:

@Jon स्कीट

कोड के लिए एक आंकड़ा संरचना का निर्माण करने में रिकर्सिवली एक पार्स पेड़ traversing है। इसलिए, उदाहरण के लिए कोड पार्स पेड़ में नोड का उपयोग करके कुछ काम करेगा और नोड के दो बच्चों पर खुद को बुलाएगा, जिससे पेड़ के लिए समग्र परिणाम देने के लिए उनके परिणाम मिलेंगे।

रिकर्सन की कुल गहराई पार्स पेड़ के आकार पर निर्भर करती है लेकिन कोड विफल होने लगता है (बिना किसी बड़े ढेर के) जब रिकर्सिव कॉल की संख्या 1000s में हो जाती है।

मुझे भी यकीन है कि कोड एक बग के कारण विफल नहीं हो रहा है क्योंकि यह छोटे इनपुट के लिए काम करता है।

+7

यहां कुछ गड़बड़ है ... stackoverflow (.com) कोई त्रुटि नहीं है! :-) –

उत्तर

72

खोलें अपने एप्लिकेशन के लिए कॉन्फ़िगरेशन चलाएं (रन/रन कॉन्फ़िगरेशन ..., फिर 'जावा एप्लिकेशन' में अनुप्रयोग प्रविष्टि की तलाश करें)।

तर्क टैब एक पाठ बॉक्स Vm तर्क, -Xss1m (या अधिकतम ढेर आकार के लिए एक बड़ा पैरामीटर) में प्रवेश किया है। डिफ़ॉल्ट मान 512 केबीटीई (सूर्य जेडीके 1.5 है - यह नहीं पता कि यह विक्रेताओं और संस्करणों के बीच भिन्न होता है)।

+2

इस मुद्दे से अवगत रहें: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6316197 –

10

वीएम तर्कों में ध्वज -Xss1024k जोड़ें।

उदाहरण के लिए -Xss1m का उपयोग करके आप mb में स्टैक आकार भी बढ़ा सकते हैं।

37

यह ढेर आकार बढ़ाकर इलाज संभव हो सकता है - लेकिन एक बेहतर समाधान बाहर काम करने के इतना recursing से बचने के लिए कैसे होगा। एक पुनरावर्ती समाधान हमेशा एक पुनरावर्तक समाधान में परिवर्तित किया जा सकता है - जो आपके कोड स्केल को बड़े इनपुट में अधिक स्पष्ट रूप से बनाएगा। अन्यथा आप वास्तव में अनुमान लगाएंगे कि कितना ढेर प्रदान करना है, जो इनपुट से भी स्पष्ट नहीं हो सकता है।

क्या आप पूरी तरह से सुनिश्चित हैं कि कोड में बग की बजाय इनपुट के आकार के कारण यह असफल रहा है? यह रिकर्सन कितना गहरा है?

संपादित करें: ठीक है, अद्यतन को देखते हुए, मैं व्यक्तिगत रूप से रिकर्सन का उपयोग करने से बचने के लिए इसे फिर से लिखने की कोशिश करता हूं। आमतौर पर "चीजें अभी भी करने" के Stack<T> होने के बाद रिकर्सन को हटाने का एक अच्छा प्रारंभिक बिंदु है।

+4

.. या पूंछ-रिकर्सन द्वारा। – BalusC

+0

मुझे jvms पर पूंछ रिकर्सन की स्थिति याद नहीं है। Tackline से क्यू टिप्पणी। –

+1

जेवीएम अभी तक एक नियम के रूप में पूंछ रिकर्स को अनुकूलित नहीं करता है। मेरा मानना ​​है कि यह उन चीजों में से एक है जो गैर-जावा भाषाओं में जेवीएम का सामान्यीकरण ठीक करना है। –

3

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

या तो F11 या Ctrl-F11 के साथ अपना प्रोग्राम चलाने के बाद, रन -> रन कॉन्फ़िगरेशन में लॉन्च कॉन्फ़िगरेशन खोलें ... और "जावा एप्लिकेशन" के तहत अपना प्रोग्राम खोलें। Arguments फलक का चयन करें, जहां आपको "VM तर्क" मिलेगा।

यह वह जगह है जहां -Xss1024k चला जाता है।

यदि आप लॉन्च कॉन्फ़िगरेशन को अपने वर्कस्पेस में फ़ाइल होना चाहते हैं (इसलिए आप राइट क्लिक कर सकते हैं और इसे चला सकते हैं), सामान्य फलक का चयन करें और सहेजें -> साझा फ़ाइल चेकबॉक्स को सहेजें और उस स्थान पर ब्राउज़ करें जिसे आप चाहते हैं लॉन्च फाइल मैं आमतौर पर उन्हें एक अलग फ़ोल्डर में रखता हूं, क्योंकि हम उन्हें सीवीएस में देखते हैं।

5

मैं भी है, जबकि XSOM लाइब्रेरी का उपयोग स्कीमा परिभाषा फ़ाइलें (XSD) पार्स करने में एक ही समस्या है

मैं 208Mb तक ढेर स्मृति में वृद्धि करने में सक्षम था तो यह heap_out_of_memory_error जिसके लिए मैं केवल 320MB तक बढ़ाने के लिए कर रहा था पता चला है।

अंतिम कॉन्फ़िगरेशन -Xmx320m -Xss208m था लेकिन फिर यह कुछ समय तक चला और असफल रहा।

मेरा फ़ंक्शन स्कीमा परिभाषा के पूरे पेड़ को दोबारा प्रिंट करता है, आश्चर्यजनक रूप से आउटपुट फ़ाइल 4 एमबी (एक्सएम लाइब्रेरी) की परिभाषा फ़ाइल के लिए 820 एमबी पार करती है जो बदले में स्कीमा परिभाषा पुस्तकालय (आईएसओ जीएमएल) के 50 एमबी का उपयोग करती है।

इसके साथ मुझे विश्वास है कि मुझे रिकर्सन से बचना है और फिर पुनरावृत्ति शुरू करना है और आउटपुट का प्रतिनिधित्व करने का कोई अन्य तरीका है, लेकिन मुझे पुनरावृत्ति के लिए सभी रिकर्सन को बदलने में थोड़ा परेशानी हो रही है।

2

तर्क -Xss काम से अस्थायी फ़ाइलों को हटाने की कोशिश नहीं करता है जब:

c:\Users\{user}\AppData\Local\Temp\. 

यह मेरे लिए चाल किया था।

0

मॉरिस इन-ऑर्डर पेड़ ट्रैवर्सल को देखें जो निरंतर स्थान का उपयोग करता है और ओ (एन) में चलता है (आपके सामान्य रिकर्सिव ट्रैवर्सल से 3 गुना लंबा - लेकिन आप अंतरिक्ष पर भारी बचत करते हैं)। यदि नोड्स संशोधित हैं, तो आप उप-पेड़ के गणना परिणाम को सहेज सकते हैं क्योंकि आप इसकी जड़ पर बैकट्रैक करते हैं (सीधे नोड पर लिखकर)।

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