স্ট্যাকওভারফ্লো এরিয়ার কী?


439

একটি কী StackOverflowError, কী কারণে এটি ঘটে এবং আমি তাদের সাথে কীভাবে আচরণ করব?


জাভাতে স্ট্যাকের আকার ছোট। এবং কিছু সময় যেমন অনেক পুনরাবৃত্তি কল আপনাকে এই সমস্যার মুখোমুখি করে। আপনি লুপ দ্বারা আপনার কোডটি আবার ডিজাইন করতে পারেন। এটি এই url এ করার জন্য আপনি সাধারণ নকশার ধরণটি খুঁজে পেতে পারেন: jndanial.com/73
JNDanial

এটি পাওয়ার একটি অ-সুস্পষ্ট উপায়: new Object() {{getClass().newInstance();}};কিছু স্থির প্রসঙ্গে লাইনটি যুক্ত করুন (যেমন mainপদ্ধতি)। উদাহরণ প্রসঙ্গে কাজ করে না (কেবল নিক্ষেপ করে InstantiationException)।
জন ম্যাকক্লেইন

উত্তর:


408

প্যারামিটার এবং স্থানীয় ভেরিয়েবলগুলি স্ট্যাকের উপর বরাদ্দ করা হয় (রেফারেন্স প্রকারের সাথে, বস্তুটি গাদাতে থাকে এবং স্তূপের মধ্যে থাকা স্ট্যাকের রেফারেন্সগুলিতে একটি ভেরিয়েবল)। স্ট্যাকটি সাধারণত আপনার ঠিকানার জায়গার উপরের প্রান্তে থাকে এবং এটি ব্যবহার করার সাথে সাথে এটি ঠিকানা জায়গার নীচের দিকে যায় (অর্থাত শূন্যের দিকে)।

আপনার প্রক্রিয়াটিরও একটি গাদা রয়েছে , যা আপনার প্রক্রিয়ার নীচে থাকে। আপনি যখন মেমরি বরাদ্দ করেন তখন এই গাদাটি আপনার ঠিকানার জায়গার উপরের প্রান্তে বাড়তে পারে। আপনি দেখতে পাচ্ছেন, স্তূপের সাথে "সংঘর্ষ" হওয়ার গাদা হওয়ার সম্ভাবনা রয়েছে (টেকটোনিক প্লেটের মতো কিছুটা !!!)।

স্ট্যাকের ওভারফ্লোর সাধারণ কারণটি হ'ল একটি খারাপ পুনরাবৃত্তি কল । সাধারণত, যখন আপনার পুনরাবৃত্ত ফাংশনগুলির সঠিক সমাপ্তির শর্ত না থাকে তখন এটি ঘটে থাকে, তাই এটি চিরকাল নিজেকে কল করে up বা সমাপ্তির শর্ত যখন ঠিক থাকে, তখন এটি পূরণের আগে অনেকগুলি পুনরাবৃত্ত কল প্রয়োজন হয়।

তবে জিইউআই প্রোগ্রামিংয়ের মাধ্যমে পরোক্ষ পুনরাবৃত্তি উত্পন্ন করা সম্ভব । উদাহরণস্বরূপ, আপনার অ্যাপ্লিকেশনটি পেইন্ট বার্তাগুলি পরিচালনা করছে এবং এগুলি প্রক্রিয়া করার সময় এটি এমন কোনও ফাংশন কল করতে পারে যা সিস্টেমটিকে অন্য একটি পেইন্ট বার্তা প্রেরণের কারণ করে। এখানে আপনি স্পষ্টভাবে নিজেকে কল করেননি, তবে ওএস / ভিএম এটি আপনার জন্য করেছে।

তাদের সাথে ডিল করার জন্য আপনাকে আপনার কোড পরীক্ষা করতে হবে। যদি আপনি নিজের কাছে কল করে এমন ফাংশনগুলি পেয়ে থাকেন তবে পরীক্ষা করুন যে আপনার একটি সমাপ্তির শর্ত রয়েছে। যদি আপনার কাছে থাকে, তবে ফাংশনটি কল করার সময় আপনি কমপক্ষে একটি আর্গুমেন্ট সংশোধন করেছেন কিনা তা পরীক্ষা করে দেখুন, অন্যথায় পুনরাবৃত্তভাবে ডাকা ফাংশনটির জন্য কোনও দৃশ্যমান পরিবর্তন হবে না এবং সমাপ্তির শর্ত অকেজো। এছাড়াও মনে রাখবেন যে আপনার স্ট্যাক স্পেসটি কোনও বৈধ সমাপ্তি শর্তে পৌঁছানোর আগে মেমরির বাইরে চলে যেতে পারে, সুতরাং আপনার পদ্ধতিটি আরও পুনরাবৃত্ত কলগুলির জন্য ইনপুট মানগুলি পরিচালনা করতে পারে তা নিশ্চিত করুন।

যদি আপনার কোনও সুস্পষ্ট পুনরাবৃত্ত ফাংশন না পাওয়া থাকে তবে আপনি এমন কোনও লাইব্রেরি ফাংশন কল করছেন কিনা তা যাচাই করে নিন যা পরোক্ষভাবে আপনার ফাংশনটি ডেকে আনবে (উপরে বর্ণিত কেসের মতো)।


1
আসল পোস্টার: আরে এটা দুর্দান্ত। সুতরাং পুনরাবৃত্তি সর্বদা স্ট্যাক ওভারফ্লো জন্য দায়ী? বা অন্যান্য জিনিসও কি তাদের জন্য দায়ী হতে পারে? দুর্ভাগ্যক্রমে আমি একটি লাইব্রেরি ব্যবহার করছি ... তবে আমি বুঝতে পারছি না এমন একটি।
Ziggy

4
হা হা হা, সুতরাং এটি এখানে: যখন (পয়েন্ট <100) {অ্যাডমাউসলিস্টনার (); moveball (); checkforcollision (); বিরতি (গতি); mouse আমি মাউস শ্রোতাদের একটি স্ট্যাকফুল দিয়ে শেষ করব তা বুঝতে না পেরে আমি কীভাবে লম্পট অনুভব করি ... ধন্যবাদ বন্ধুরা!
জিগি

4
না, স্ট্যাকের ওভারফ্লোগুলি ভেরিয়েবলগুলি থেকে খুব বড় হয়েও স্ট্যাকের জন্য বরাদ্দ করতে পারে যদি আপনি এটিতে উইকিপিডিয়া নিবন্ধটি en.wikedia.org/wiki/Stack_overflow এ সন্ধান করেন
জেবি কিং

8
এটি চিহ্নিত করা উচিত যে স্ট্যাক ওভারফ্লো ত্রুটিটি "পরিচালনা" করা প্রায় অসম্ভব। বেশিরভাগ পরিবেশে, ত্রুটিটি পরিচালনা করার জন্য স্ট্যাকের কোড চালানো দরকার, যা যদি স্ট্যাকের আরও কোনও জায়গা না থাকে তবে তা কঠিন।
হট লিকস

3
@ জেবি কিং: জাভাতে আসলেই প্রযোজ্য না, যেখানে কেবল আদিম ধরণের এবং উল্লেখগুলি স্ট্যাকের উপরে রাখা হয়। সমস্ত বড় জিনিস (অ্যারে এবং অবজেক্টস) গাদা হয়ে আছে।
জ্যাকসাহ্নওয়াল্ড্ট GoFundMonica

107

এটি বর্ণনা করতে প্রথমে বুঝতে পারি কীভাবে স্থানীয় ভেরিয়েবল এবং অবজেক্টগুলি সংরক্ষণ করা হয়।

স্থানীয় ভেরিয়েবল স্ট্যাকের মধ্যে সংরক্ষণ করা হয় : এখানে চিত্র বর্ণনা লিখুন

আপনি যদি চিত্রটির দিকে তাকান তবে আপনার বুঝতে হবে কীভাবে জিনিসগুলি কাজ করছে।

যখন কোনও জাভা অ্যাপ্লিকেশন দ্বারা কোনও ফাংশন কল শুরু করা হয়, কল স্ট্যাকের উপর একটি স্ট্যাক ফ্রেম বরাদ্দ করা হয়। স্ট্যাক ফ্রেমে আমন্ত্রিত পদ্ধতির প্যারামিটারগুলি, এর স্থানীয় পরামিতিগুলি এবং পদ্ধতির ফেরতের ঠিকানা রয়েছে। প্রত্যাবর্তনের ঠিকানাটি কার্যকর করা পয়েন্টটিকে বোঝায় যা থেকে, প্রোগ্রামটি কার্যকর করা অনুরোধকৃত পদ্ধতিটি ফিরে আসার পরে চলতে থাকবে। যদি কোনও নতুন স্ট্যাক ফ্রেমের জন্য জায়গা না থাকে 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 এবং এর ক্রমবর্ধমান অনুসারীদের থেকে প্যারামিটারে পাস করেছি, ফলস্বরূপ, পুনরাবৃত্তি কখনই শেষ হবে না।

-Xss1M1 এমবি সমান থ্রেড স্ট্যাকের আকার নির্দিষ্ট করে এমন পতাকা ব্যবহার করে একটি নমুনা কার্যকরকরণ, নীচে দেখানো হয়েছে:

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 তা নিক্ষেপ করা হবে। সতর্কতা অবলম্বন না করা হলে পুনরাবৃত্তি কীভাবে সমস্যা সৃষ্টি করতে পারে তার একটি উদাহরণ খুব ভাল উদাহরণ।

স্ট্যাকওভারফ্লো এরিয়ারটি কীভাবে মোকাবেলা করবেন

  1. সহজ সমাধানটি হ'ল স্ট্যাক ট্রেসটি সাবধানে পরীক্ষা করা এবং লাইন সংখ্যার পুনরাবৃত্তি প্যাটার্নটি সনাক্ত করা। এই লাইন নম্বরগুলি কোডটি পুনরাবৃত্তভাবে বলা হচ্ছে তা নির্দেশ করে। একবার আপনি এই লাইনগুলি শনাক্ত করার পরে, আপনাকে অবশ্যই নিজের কোডটি অবশ্যই যত্ন সহকারে পরীক্ষা করতে হবে এবং বুঝতে হবে কেন পুনরাবৃত্তি কখনই বন্ধ হয় না।

  2. যদি আপনি যাচাই করে ফেলেছেন যে পুনরাবৃত্তিটি সঠিকভাবে প্রয়োগ করা হয়েছে, তবে আপনি বৃহত্তর সংখ্যার অনুরোধকে মঞ্জুরি দেওয়ার জন্য, স্ট্যাকের আকার বাড়াতে পারেন। ইনস্টল করা জাভা ভার্চুয়াল মেশিনের (জেভিএম) উপর নির্ভর করে, ডিফল্ট থ্রেড স্ট্যাকের আকার 512KB বা 1MB এর সমান হতে পারে । আপনি -Xssপতাকাটি ব্যবহার করে থ্রেড স্ট্যাকের আকার বাড়াতে পারেন । এই পতাকাটি হয় প্রকল্পের কনফিগারেশন বা কমান্ড লাইনের মাধ্যমে নির্দিষ্ট করা যেতে পারে। -Xssযুক্তির বিন্যাসটি হ'ল: -Xss<size>[g|G|m|M|k|K]


উইন্ডোজ ব্যবহার করার সময় কিছু জাভা সংস্করণগুলিতে একটি ত্রুটি রয়েছে বলে মনে হচ্ছে যেখানে -এসএস যুক্তি কেবল নতুন থ্রেডগুলিতে কার্যকর হয়
goerlibe

65

আপনার যদি এমন কোনও ফাংশন থাকে:

int foo()
{
    // more stuff
    foo();
}

তারপরে foo () নিজেকে আরও গভীর ও গভীরতর করে তুলবে, এবং যখন আপনি কোন ফাংশনগুলিতে ভরিয়েছেন তা ট্র্যাক রাখার জন্য স্থানটি ব্যবহার করা হবে তখন আপনি স্ট্যাকের ওভারফ্লো ত্রুটি পাবেন।


12
ভুল। আপনার ফাংশনটি পুচ্ছ-পুনরাবৃত্ত হয়। বেশিরভাগ সংকলিত ভাষাগুলিতে লেজ-পুনরাবৃত্তি অপ্টিমাইজেশন রয়েছে। এর অর্থ হ'ল পুনরাবৃত্তিটি একটি সাধারণ লুপে কমে যায় এবং আপনি কোনও কোনও সিস্টেমে কোডের এই টুকরোটি দিয়ে স্ট্যাকের ওভারফ্লোতে কখনও আঘাত করতে পারবেন না।
9:39 তে আনন্দিত

উদ্দীপনা, কোন অ-কার্যকরী ভাষাগুলি পুচ্ছ পুনরাবৃত্তি সমর্থন করে?
ঘোড়াগুয়ের

@ বিনিস্টার এবং জাভাস্ক্রিপ্টের কিছু বাস্তবায়ন
পেসারিয়ার

@ ঘোড়ায়গুই স্কালার টেল পুনর্বিবেচনার পক্ষে সমর্থন রয়েছে।
অজিত কেসাগর

এটি স্ট্যাকের ওভারফ্লো কী কী তৈরি করতে পারে তার সারাংশ গ্রহণ করে। খুশী হলাম।
পিক্সেল

24

স্ট্যাক ওভারফ্লো মানে হ'ল: একটি স্ট্যাক ওভারফ্লো। প্রোগ্রামে সাধারণত একটি স্ট্যাক থাকে যেখানে লোকাল-স্কোপ ভেরিয়েবল এবং অ্যাড্রেস থাকে যেখানে একটি রুটিন কার্যকর হওয়ার পরে ফিরে আসা উচিত। এই স্ট্যাকটি মেমরির কোথাও একটি স্থির মেমরির পরিসীমা হতে থাকে, সুতরাং এটিতে কতটা মান থাকতে পারে তা সীমিত।

স্ট্যাকটি খালি থাকলে আপনি পপ করতে পারবেন না, আপনি যদি করেন তবে স্ট্যাকের আন্ডারফ্লো ত্রুটি পাবেন।

স্ট্যাকটি পূর্ণ হলে আপনি ধাক্কা দিতে পারবেন না, আপনি যদি তা করেন তবে স্ট্যাকের ওভারফ্লো ত্রুটি পাবেন।

আপনি যেখানে স্ট্যাকের মধ্যে খুব বেশি বরাদ্দ করেন সেখানে স্ট্যাক ওভারফ্লো উপস্থিত হয়। উদাহরণস্বরূপ, উল্লিখিত পুনরাবৃত্তি।

কিছু বাস্তবায়ন পুনরাবৃত্তি কিছু ফর্ম অপ্টিমাইজ। বিশেষ করে লেজ পুনরাবৃত্তি। টেল রিকার্সিভ রুটিনগুলি রুটিনের ফর্ম যেখানে রিকার্সিভ কলটি রুটিনটি কী করে তা চূড়ান্ত জিনিস হিসাবে উপস্থিত হয়। এই ধরণের রুটিন কলটি কেবল লাফিয়ে কমে যায়।

কিছু বাস্তবায়ন পুনরাবৃত্তির জন্য তাদের নিজস্ব স্ট্যাকগুলি প্রয়োগ করতে এতদূর চলে যায়, সুতরাং তারা সিস্টেমটির স্মৃতিশক্তি শেষ না হওয়া পর্যন্ত পুনরাবৃত্তি চালিয়ে যেতে দেয়।

আপনি যা চেষ্টা করতে পারেন তার চেয়ে সহজ জিনিস হ'ল আপনি যদি পারেন তবে আপনার স্ট্যাকের আকার বাড়িয়ে তুলতে পারেন। আপনি যদি তা না করতে পারেন তবে দ্বিতীয় সেরা জিনিসটি হ'ল স্ট্যাকের অতিরিক্ত প্রবাহের জন্য স্পষ্টভাবে এমন কিছু আছে কিনা তা দেখা উচিত। রুটিনে কল করার আগে এবং পরে কিছু মুদ্রণ করে এটি ব্যবহার করে দেখুন। এটি আপনাকে ব্যর্থ রুটিন খুঁজে পেতে সহায়তা করে।


4
স্ট্যাক আন্ডারফ্লো হিসাবে এমন কিছু আছে ?
পেসারিয়ার

5
সমাবেশে একটি স্ট্যাক আন্ডারফ্লো সম্ভব (আপনার চাপের চেয়ে বেশি পপিং করা), যদিও সংকলিত ভাষায় এটি অসম্ভবের কাছাকাছি থাকত। আমি নিশ্চিত নই, আপনি সি এর বরাদ্দ () যা নেতিবাচক আকারকে "সমর্থন করে" এর একটি বাস্তবায়ন পেতে সক্ষম হতে পারেন।
স্কোর_উন্ডারে

2
স্ট্যাক ওভারফ্লো অর্থ হ'ল: একটি স্ট্যাক ওভারফ্লো। প্রোগ্রামে সাধারণত একটি স্ট্যাক থাকে যার মধ্যে লোকাল-স্কোপ ভেরিয়েবলগুলি থাকে -> না, প্রতিটি থ্রেডের নিজস্ব স্ট্যাক রয়েছে যার মধ্যে স্থানীয় ভেরিয়েবলগুলি রয়েছে এমন প্রতিটি পদ্ধতির অনুরোধের জন্য স্ট্যাক ফ্রেম রয়েছে ..
Koray Tugay

9

একটি স্ট্যাক ওভারফ্লো সাধারণত নীচে বাসা বাঁধার ফাংশন কলগুলি দ্বারা ডাকা হয় (বিশেষত পুনরাবৃত্তি ব্যবহারের সময় সহজ, অর্থাত্ একটি ফাংশন যা নিজেকে কল করে) বা স্ট্যাকের যেখানে প্রচুর পরিমাণে হিপ ব্যবহার করা আরও উপযুক্ত হবে তার জন্য প্রচুর পরিমাণে মেমরি বরাদ্দ করে।


1
ওহো, জাভা ট্যাগটি দেখেনি
গ্রেগ

এছাড়াও, এখানে মূল পোস্টার থেকে: বাসা বাঁধে খুব গভীরভাবে কোনটিতে? অন্যান্য কাজ? এবং: একজন কীভাবে স্ট্যাক বা হিপগুলিকে মেমরি বরাদ্দ করে (যেহেতু, আপনি জানেন যে, আমি স্পষ্টভাবে না জেনে এই বিষয়গুলির মধ্যে একটি করেছি)।
Ziggy

@ জিগি: হ্যাঁ, যদি কোনও ফাংশন অন্য ফাংশনটিকে কল করে, যা আরও একটি ফাংশন কল করে এবং আরও অনেক স্তরের পরে, আপনার প্রোগ্রামটির স্ট্যাক ওভারফ্লো হবে। [অব্যাহত]
ক্রিস জেস্টার-ইয়ং

[... অব্যাহত] জাভাতে, আপনি সরাসরি স্ট্যাক থেকে মেমরি বরাদ্দ করতে পারবেন না (যেখানে সি তে, আপনি এটি করতে পারেন, এবং এটি তখন দেখার মতো কিছু হবে), যার কারণ হওয়ার সম্ভাবনা কম। জাভাতে, সমস্ত নতুন বরাদ্দ "নতুন" ব্যবহার করে গাদা থেকে আসে।
ক্রিস জেস্টার-ইয়ং

@ ক্রিসজেস্টার-ইয়ং এটা কি সত্য নয় যে কোনও পদ্ধতিতে আমার যদি 100 স্থানীয় ভেরিয়েবল থাকে তবে এগুলি সবই ব্যতিক্রম ছাড়াই স্ট্যাকে চলে যায়?
পেসারিয়ার

7

যেমনটি আপনি বলেছেন, আপনাকে কিছু কোড দেখাতে হবে। :-)

আপনার ফাংশন খুব গভীরভাবে নীড় কল করলে সাধারণত একটি স্ট্যাক ওভারফ্লো ত্রুটি ঘটে। এটি কীভাবে ঘটে তার কয়েকটি উদাহরণের জন্য স্ট্যাক ওভারফ্লো কোড গল্ফ থ্রেডটি দেখুন (যদিও সেই প্রশ্নের ক্ষেত্রে, উত্তরগুলি ইচ্ছাকৃতভাবে স্ট্যাকের ওভারফ্লো করে)।


1
আমি সম্পূর্ণরূপে কোড যুক্ত করতে চাই, তবে স্ট্যাকের অতিরিক্ত প্রবাহের কারণ কীভাবে আমি জানি না কোন কোডটি যুক্ত করা উচিত তা আমি নিশ্চিত নই। সমস্ত কোড যুক্ত করা লম্পট হবে, না?
Ziggy

আপনার প্রকল্পটি কি ওপেন সোর্স? যদি তা হয় তবে কেবল একটি সোর্সফোর্জ বা গিথব অ্যাকাউন্ট তৈরি করুন এবং আপনার সমস্ত কোড সেখানে আপলোড করুন। :-)
ক্রিস জেস্টার-ইয়াং

এটি দুর্দান্ত ধারণা মত শোনাচ্ছে তবে আমি এমন নুব যা আমার আপলোড করতে হবে তা আমি জানি না। যেমন, আমি যে লাইব্রেরিটি ক্লাস আমদানি করছি যা আমি প্রসারিত করছি ইত্যাদি ... সবই আমার অজানা। ওহ মানুষ: খারাপ সময়।
জিগি

5

স্ট্যাক ওভারফ্লোগুলির সর্বাধিক সাধারণ কারণ হ'ল অতিরিক্ত গভীর বা অসীম পুনরাবৃত্তি । এটি যদি আপনার সমস্যা হয় তবে জাভা রিকার্সন সম্পর্কে এই টিউটোরিয়ালটি সমস্যাটি বুঝতে সহায়তা করতে পারে।


5

StackOverflowErrorগাদা হিসাবে স্ট্যাক হয় OutOfMemoryError

আনবাউন্ডেড পুনরাবৃত্ত কলগুলির ফলে স্ট্যাক স্পেস ব্যবহার করা হয়।

নিম্নলিখিত উদাহরণ উত্পাদন করে StackOverflowError:

class  StackOverflowDemo
{
    public static void unboundedRecursiveCall() {
     unboundedRecursiveCall();
    }

    public static void main(String[] args) 
    {
        unboundedRecursiveCall();
    }
}

StackOverflowError যদি পুনরাবৃত্তি কলগুলি অসম্পূর্ণ ইন-মেমরি কলগুলির (বাইটগুলিতে) মোট স্ট্যাকের আকার (বাইটে) অতিক্রম করতে না পারে তার জন্য মোট বেঁধে দেওয়া যায় avoid


3

একক লিঙ্কযুক্ত তালিকার বিপরীত করার জন্য এটি পুনরাবৃত্ত আলগোরিদিমের একটি উদাহরণ। নিম্নলিখিত স্পেস (4 জি মেমরি, ইন্টেল কোর আই 5 2.3GHz সিপিইউ, 64 বিট উইন্ডোজ 7) সহ একটি ল্যাপটপে, 10,000 টির কাছাকাছি আকারের লিঙ্কযুক্ত তালিকার জন্য এই ফাংশনটি স্ট্যাকওভারফ্লো ত্রুটিতে চলে যাবে।

আমার বক্তব্যটি হ'ল আমাদের সিস্টেমের স্কেলটি সর্বদা বিবেচনায় রেখে ন্যায়বিচারের সাথে পুনরাবৃত্তিটি ব্যবহার করা উচিত। প্রায়শই পুনরাবৃত্তি পুনরাবৃত্তি প্রোগ্রামে রূপান্তর করা যেতে পারে, যা আরও ভাল স্কেল les (একই অ্যালগরিদমের একটি পুনরাবৃত্ত সংস্করণ পৃষ্ঠার নীচে দেওয়া হয়েছে, এটি 9 মিলিসেকেন্ডে 1 মিলিয়ন মাপের একক লিঙ্কযুক্ত তালিকার বিপরীত))

    private static LinkedListNode doReverseRecursively(LinkedListNode x, LinkedListNode first){

    LinkedListNode second = first.next;

    first.next = x;

    if(second != null){
        return doReverseRecursively(first, second);
    }else{
        return first;
    }
}

public static LinkedListNode reverseRecursively(LinkedListNode head){
    return doReverseRecursively(null, head);
}

একই অ্যালগরিদমের Iterative সংস্করণ:

    public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}   

private static LinkedListNode doReverseIteratively(LinkedListNode x, LinkedListNode first) {

    while (first != null) {
        LinkedListNode second = first.next;
        first.next = x;
        x = first;

        if (second == null) {
            break;
        } else {
            first = second;
        }
    }
    return first;
}


public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}

আমি জেভিএম এর সাথে ভাবি, আপনার ল্যাপটপটি যা অনুমান করে তা আসলে কিছু যায় আসে না।
কেভিন

3

একটি StackOverflowErrorজাভা একটি রানটাইম ত্রুটি।

জেভিএম দ্বারা বরাদ্দকৃত কল স্ট্যাক মেমরির পরিমাণ ছাড়িয়ে গেলে এটি নিক্ষেপ করা হয়।

StackOverflowErrorনিক্ষিপ্ত হওয়ার সাধারণ ঘটনাটি হ'ল যখন অতিরিক্ত গভীর বা অসীম পুনরাবৃত্তির কারণে কল স্ট্যাকটি ছাড়িয়ে যায়।

উদাহরণ:

public class Factorial {
    public static int factorial(int n){
        if(n == 1){
            return 1;
        }
        else{
            return n * factorial(n-1);
        }
    }

    public static void main(String[] args){
        System.out.println("Main method started");
        int result = Factorial.factorial(-1);
        System.out.println("Factorial ==>"+result);
        System.out.println("Main method ended");
    }
}

স্ট্যাক ট্রেস:

Main method started
Exception in thread "main" java.lang.StackOverflowError
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)

উপরের ক্ষেত্রে, প্রোগ্রাম্যাটিক পরিবর্তন করে এড়ানো যায়। তবে যদি প্রোগ্রামটির যুক্তি সঠিক হয় এবং এটি এখনও ঘটে তবে আপনার স্ট্যাকের আকার বাড়ানো দরকার।


0

এই একটি আদর্শ ক্ষেত্রে দেখা যায় java.lang.StackOverflowError... পদ্ধতি যাও recursively কোন থেকে বেরিয়ে যাওয়ার জন্য নিজেই কল করছে doubleValue(), floatValue()ইত্যাদি

Rational.java

    public class Rational extends Number implements Comparable<Rational> {
        private int num;
        private int denom;

        public Rational(int num, int denom) {
            this.num = num;
            this.denom = denom;
        }

        public int compareTo(Rational r) {
            if ((num / denom) - (r.num / r.denom) > 0) {
                return +1;
            } else if ((num / denom) - (r.num / r.denom) < 0) {
                return -1;
            }
            return 0;
        }

        public Rational add(Rational r) {
            return new Rational(num + r.num, denom + r.denom);
        }

        public Rational sub(Rational r) {
            return new Rational(num - r.num, denom - r.denom);
        }

        public Rational mul(Rational r) {
            return new Rational(num * r.num, denom * r.denom);
        }

        public Rational div(Rational r) {
            return new Rational(num * r.denom, denom * r.num);
        }

        public int gcd(Rational r) {
            int i = 1;
            while (i != 0) {
                i = denom % r.denom;
                denom = r.denom;
                r.denom = i;
            }
            return denom;
        }

        public String toString() {
            String a = num + "/" + denom;
            return a;
        }

        public double doubleValue() {
            return (double) doubleValue();
        }

        public float floatValue() {
            return (float) floatValue();
        }

        public int intValue() {
            return (int) intValue();
        }

        public long longValue() {
            return (long) longValue();
        }
    }

Main.java

    public class Main {

        public static void main(String[] args) {

            Rational a = new Rational(2, 4);
            Rational b = new Rational(2, 6);

            System.out.println(a + " + " + b + " = " + a.add(b));
            System.out.println(a + " - " + b + " = " + a.sub(b));
            System.out.println(a + " * " + b + " = " + a.mul(b));
            System.out.println(a + " / " + b + " = " + a.div(b));

            Rational[] arr = {new Rational(7, 1), new Rational(6, 1),
                    new Rational(5, 1), new Rational(4, 1),
                    new Rational(3, 1), new Rational(2, 1),
                    new Rational(1, 1), new Rational(1, 2),
                    new Rational(1, 3), new Rational(1, 4),
                    new Rational(1, 5), new Rational(1, 6),
                    new Rational(1, 7), new Rational(1, 8),
                    new Rational(1, 9), new Rational(0, 1)};

            selectSort(arr);

            for (int i = 0; i < arr.length - 1; ++i) {
                if (arr[i].compareTo(arr[i + 1]) > 0) {
                    System.exit(1);
                }
            }


            Number n = new Rational(3, 2);

            System.out.println(n.doubleValue());
            System.out.println(n.floatValue());
            System.out.println(n.intValue());
            System.out.println(n.longValue());
        }

        public static <T extends Comparable<? super T>> void selectSort(T[] array) {

            T temp;
            int mini;

            for (int i = 0; i < array.length - 1; ++i) {

                mini = i;

                for (int j = i + 1; j < array.length; ++j) {
                    if (array[j].compareTo(array[mini]) < 0) {
                        mini = j;
                    }
                }

                if (i != mini) {
                    temp = array[i];
                    array[i] = array[mini];
                    array[mini] = temp;
                }
            }
        }
    }

ফলাফল

    2/4 + 2/6 = 4/10
    Exception in thread "main" java.lang.StackOverflowError
    2/4 - 2/6 = 0/-2
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
    2/4 * 2/6 = 4/24
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
    2/4 / 2/6 = 12/8
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)
        at com.xetrasu.Rational.doubleValue(Rational.java:64)

এখানে StackOverflowErrorওপেনজেডকে 7- এর উত্স কোড


0

ক্রাঞ্চে, নীচে পরিস্থিতি স্ট্যাকের ওভারফ্লো ত্রুটি এনে দেবে।

public class Example3 {

public static void main(String[] args) {

    main(new String[1]);

}

}


-1

এখানে একটি উদাহরণ

public static void main(String[] args) {
    System.out.println(add5(1));
}

public static int add5(int a) {
    return add5(a) + 5;
}

একটি স্ট্যাকওভারফ্লো এরির মূলত হ'ল আপনি যখন কিছু করার চেষ্টা করেন, সম্ভবত এটি নিজেকে ডেকে নিয়ে যায় এবং অনন্তের দিকে চলে যায় (বা এটি স্ট্যাকওভারফ্লো এরিয়ার না দেওয়া পর্যন্ত)।

add5(a) নিজেকে কল করবে এবং তারপরে আবার নিজেকে কল করবে, ইত্যাদি।


-1

"স্ট্যাক ওভাররন (ওভারফ্লো)" শব্দটি প্রায়শই ব্যবহৃত হয় তবে একটি মিসনোমার; আক্রমণগুলি স্ট্যাকটিকে উপচে ফেলে না তবে স্ট্যাকের উপর বাফার করে।

- অধ্যাপক ড। ডিয়েটার গলম্যানের বক্তৃতা স্লাইডগুলি থেকে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.