मुझे लगता है कि दूसरों ने यह समझाने का अच्छा काम किया है कि क्यों cnt> 0, लेकिन cnt = 4 के बारे में पर्याप्त विवरण नहीं है, और cnt अलग-अलग सेटिंग्स के बीच इतने व्यापक रूप से भिन्न क्यों है। मैं यहां उस शून्य को भरने का प्रयास करूंगा।
चलो
- X कुल स्टैक आकार है
- जब हम पहली बार मुख्य प्रवेश करते हैं तो स्टैक स्पेस का उपयोग किया जाता है
- हर बार जब हम मुख्य में प्रवेश करते हैं तो स्टैक स्पेस में वृद्धि होती है
- P चलाने के लिए आवश्यक स्टैक स्थान होना चाहिए
System.out.println
जब हम पहली बार मुख्य में आते हैं, तो बचा हुआ स्थान एक्सएम होता है। प्रत्येक पुनरावर्ती कॉल R अधिक मेमोरी लेता है। तो 1 पुनरावर्ती कॉल (मूल से 1 अधिक) के लिए, मेमोरी उपयोग M + R है। मान लीजिए कि St सफलOverflowError C सफल पुनरावर्ती कॉल के बाद फेंक दिया जाता है, अर्थात M + C * R <= X और M + C * (R +) 1)> X. पहली StackOverflowError के समय, X - M - C * R मेमोरी बची है।
चलाने में सक्षम होना System.out.prinln
, हमें स्टैक पर बचे हुए स्थान की P राशि की आवश्यकता है। यदि ऐसा होता है कि एक्स - एम - सी * आर> = पी, तो 0 मुद्रित किया जाएगा। यदि P को अधिक स्थान की आवश्यकता है, तो हम cnt ++ की कीमत पर R मेमोरी प्राप्त करके, स्टैक से फ्रेम निकालते हैं।
जब println
आखिरकार चलाने में सक्षम है, तो X - M - (C - cnt) * R> = P. इसलिए यदि P किसी विशेष प्रणाली के लिए बड़ा है, तो cnt बड़ा होगा।
आइए इसे कुछ उदाहरणों के साथ देखें।
उदाहरण 1: मान लीजिए
- एक्स = 100
- एम = 1
- आर = 2
- पी = 1
फिर सी = मंजिल ((एक्सएम) / आर) = 49, और सेंट = छत ((पी - (एक्स - एम - सी * आर)) / आर) = 0।
उदाहरण 2: मान लीजिए कि
- एक्स = 100
- एम = 1
- आर = ५
- पी = 12
फिर C = 19, और cnt = 2।
उदाहरण 3: मान लीजिए कि
- एक्स = 101
- एम = 1
- आर = ५
- पी = 12
फिर C = 20, और cnt = 3।
उदाहरण 4: मान लीजिए कि
- एक्स = 101
- म = २
- आर = ५
- पी = 12
फिर C = 19, और cnt = 2।
इस प्रकार, हम देखते हैं कि सिस्टम (M, R, और P) और स्टैक आकार (X) दोनों ही cnt को प्रभावित करते हैं।
एक साइड नोट के रूप में, इससे कोई फर्क नहीं पड़ता कि कितना स्थान catch
शुरू करने की आवश्यकता है। जब तक के लिए पर्याप्त जगह नहीं है catch
, तब तक cnt नहीं बढ़ेगा, इसलिए कोई बाहरी प्रभाव नहीं हैं।
संपादित करें
मैंने जो कहा उसके बारे में वापस लेता हूं catch
। यह एक भूमिका निभाता है। मान लीजिए कि इसे शुरू करने के लिए टी राशि की जगह चाहिए। जब बायाँ स्थान T से अधिक होता है, और cnt वृद्धि करना शुरू कर देता हैprintln
जब बायाँ स्थान T + P से बड़ा होता है, तो यह गणना के लिए एक अतिरिक्त कदम जोड़ता है और पहले से मैला विश्लेषण को आगे बढ़ाता है।
संपादित करें
मुझे अंततः अपने सिद्धांत का समर्थन करने के लिए कुछ प्रयोग चलाने का समय मिला। दुर्भाग्य से, सिद्धांत प्रयोगों के साथ मेल नहीं खाता है। वास्तव में जो होता है वह बहुत अलग होता है।
प्रयोग सेटअप: डिफ़ॉल्ट जावा और डिफ़ॉल्ट- jdk के साथ Ubuntu 12.04 सर्वर। Xss 70,000 से 1 बाइट की वृद्धि पर 460,000 से शुरू होता है।
परिणाम यहां उपलब्ध हैं: https://www.google.com/fusiontables/DataSource?docid=1xkJhd4s8biLghe6gZbcfUs3vT5MpS_OnscjwWDMM
मैंने एक और संस्करण बनाया है जहां हर दोहराया डेटा बिंदु हटा दिया जाता है। दूसरे शब्दों में, केवल उन बिंदुओं को दिखाया गया है जो पहले से भिन्न हैं। इससे विसंगतियों को देखना आसान हो जाता है। https://www.google.com/fusiontables/DataSource?docid=1XG_SRzrrNasepwZoNHqEAKuZlHiAm9vbEdwfsUA