इसका वर्णन करने के लिए, पहले हमें यह समझना चाहिए कि स्थानीय चर और वस्तुएं कैसे संग्रहीत की जाती हैं।
स्थानीय चर में जमा हो जाती ढेर :
यदि आपने छवि को देखा तो आपको यह समझने में सक्षम होना चाहिए कि चीजें कैसे काम कर रही हैं।
जब एक फ़ंक्शन कॉल जावा एप्लिकेशन द्वारा मंगाई जाती है, तो कॉल स्टैक पर स्टैक फ्रेम आवंटित किया जाता है। स्टैक फ्रेम में शामिल विधि के पैरामीटर, इसके स्थानीय पैरामीटर और विधि का वापसी पता शामिल है। वापसी का पता निष्पादन बिंदु को दर्शाता है, जिसमें से लागू होने के बाद प्रोग्राम निष्पादन जारी रहेगा। यदि नए स्टैक फ्रेम के लिए कोई स्थान नहीं है, तो StackOverflowError
जावा वर्चुअल मशीन (जेवीएम) द्वारा फेंक दिया जाता है।
सबसे आम मामला जो संभवतः जावा एप्लिकेशन के ढेर को समाप्त कर सकता है, वह पुनरावृत्ति है। पुनरावृत्ति में, एक विधि अपने निष्पादन के दौरान खुद को आमंत्रित करती है। रिकर्सियन को एक शक्तिशाली सामान्य-प्रयोजन प्रोग्रामिंग तकनीक के रूप में माना जाता है, लेकिन इससे बचने के लिए सावधानी के साथ उपयोग किया जाना चाहिएStackOverflowError
।
StackOverflowError
नीचे फेंकने का एक उदाहरण नीचे दिखाया गया है:
StackOverflowErrorExample.java:
public class StackOverflowErrorExample {
public static void recursivePrint(int num) {
System.out.println("Number: " + num);
if (num == 0)
return;
else
recursivePrint(++num);
}
public static void main(String[] args) {
StackOverflowErrorExample.recursivePrint(1);
}
}
इस उदाहरण में, हम एक पुनरावर्ती विधि को परिभाषित करते हैं, जिसे recursivePrint
एक पूर्णांक प्रिंट करता है और फिर, एक तर्क के रूप में अगले क्रमिक पूर्णांक के साथ खुद को कॉल करता है। जब तक हम 0
एक पैरामीटर के रूप में पास नहीं करते तब तक पुनरावृत्ति समाप्त हो जाती है । हालांकि, हमारे उदाहरण में, हम 1 और इसके बढ़ते अनुयायियों से पैरामीटर में पारित हुए, नतीजतन, पुनरावृत्ति कभी भी समाप्त नहीं होगी।
एक नमूना निष्पादन, -Xss1M
1 एमबी के बराबर थ्रेड स्टैक के आकार को निर्दिष्ट करने वाले ध्वज का उपयोग करके नीचे दिखाया गया है:
Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:480)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.write(PrintStream.java:527)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
...
जेवीएम के प्रारंभिक कॉन्फ़िगरेशन के आधार पर, परिणाम भिन्न हो सकते हैं, लेकिन अंततः StackOverflowError
फेंक दिया जाएगा। यह उदाहरण एक बहुत अच्छा उदाहरण है कि कैसे पुनरावृत्ति समस्याओं का कारण बन सकती है, यदि सावधानी के साथ लागू नहीं किया गया है।
StackOverflowError से कैसे निपटें
सबसे सरल समाधान स्टैक ट्रेस का सावधानीपूर्वक निरीक्षण करना और रेखा संख्याओं के दोहराव पैटर्न का पता लगाना है। ये पंक्ति संख्या कोड को पुनरावृत्ति कहे जाने का संकेत देती है। एक बार जब आप इन पंक्तियों का पता लगा लेते हैं, तो आपको अपने कोड का सावधानीपूर्वक निरीक्षण करना चाहिए और समझना चाहिए कि पुनरावृत्ति कभी समाप्त क्यों नहीं होती है।
यदि आपने सत्यापित किया है कि पुनरावृत्ति को सही तरीके से लागू किया गया है, तो आप बड़ी संख्या में इनवोकेशन की अनुमति देने के लिए, स्टैक का आकार बढ़ा सकते हैं। स्थापित जावा वर्चुअल मशीन (JVM) के आधार पर, डिफ़ॉल्ट थ्रेड स्टैक आकार 512KB, या 1MB के बराबर हो सकता है । आप -Xss
ध्वज का उपयोग करके थ्रेड स्टैक का आकार बढ़ा सकते हैं । यह ध्वज या तो प्रोजेक्ट के कॉन्फ़िगरेशन के माध्यम से, या कमांड लाइन के माध्यम से निर्दिष्ट किया जा सकता है। -Xss
तर्क का प्रारूप
है:
-Xss<size>[g|G|m|M|k|K]