কি কারণ হতে পারে java.lang.StackOverflowError
? আমি যে স্ট্যাক প্রিন্টআউট পাই তা মোটেও গভীর নয় (কেবল 5 টি পদ্ধতি)।
উত্তর:
পদ্ধতির জন্য যেকোন পুনরুদ্ধারযোগ্য কলগুলির জন্য পরীক্ষা করুন। মূলত যখন কোনও পদ্ধতির জন্য পুনরাবৃত্তি কল আসে তখন এটি ঘটে। একটি সহজ উদাহরণ
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
এখানে System.out.println (i); টেস্টমেডোড ডাকা হলে বারবার স্ট্যাকের দিকে ঠেলে দেওয়া হবে।
জেভিএম-তে একটি (alচ্ছিক) যুক্তি হ'ল স্ট্যাক আকার size এটি -এসএসএস আমি ডিফল্ট মানটি কী তা জানি না, তবে স্ট্যাকের সামগ্রীর পরিমাণ যদি সেই মানটি ছাড়িয়ে যায় তবে আপনি ত্রুটি পাবেন get
সাধারণত, অসীম পুনরাবৃত্তি এটির কারণ, তবে আপনি যদি এটি দেখছিলেন, আপনার স্ট্যাক ট্রেসটিতে 5 টি ফ্রেমের বেশি থাকবে।
এটি দূরে যায় কিনা তা দেখার জন্য একটি-এক্সএস আর্গুমেন্ট যুক্ত করার চেষ্টা করুন (বা এর মান বাড়ানো)।
আসলে কোন জাভা.লং.স্ট্যাক ওভারফ্লো এরিয়ার কারণ হয় তা সাধারণত অনিচ্ছাকৃত পুনরাবৃত্তি। আমার জন্য প্রায়শই যখন আমি ওভারিডিড পদ্ধতির জন্য একটি সুপার পদ্ধতি কল করার ইচ্ছা করি। যেমন এই ক্ষেত্রে:
public class Vehicle {
public void accelerate(float acceleration, float maxVelocity) {
// set the acceleration
}
}
public class SpaceShip extends Vehicle {
@Override
public void accelerate(float acceleration, float maxVelocity) {
// update the flux capacitor and call super.accelerate
// oops meant to call super.accelerate(acceleration, maxVelocity);
// but accidentally wrote this instead. A StackOverflow is in our future.
this.accelerate(acceleration, maxVelocity);
}
}
প্রথমত, যখন আমরা কোনও ফাংশন বলি তখন পর্দার আড়ালে কী ঘটে তা জেনে রাখা দরকারী। পদ্ধতিটি যেখানে ডাকা হয়েছিল তার যুক্তি এবং ঠিকানাটিকে স্ট্যাকের উপর চাপ দেওয়া হয় (দেখুন http://en.wikedia.org/wiki/Stack_(abstract_data_type)# রানটাইম_মেমরি_ পরিচালন ) যাতে তথাকথিত পদ্ধতিটি আর্গুমেন্টগুলিতে অ্যাক্সেস করতে পারে এবং যখন ডাকা পদ্ধতিটি সম্পন্ন হয়েছে, কল করার পরে কার্যকর করা চালিয়ে যেতে পারে। তবে যেহেতু আমরা এটিকে বলি (ত্বরণ, সর্বোচ্চগতি) পুনরাবৃত্তভাবে বলছি (যখন কোনও পদ্ধতি নিজেকে কল করে তখন পুনরাবৃত্তি হ'ল আরও তথ্যের জন্য দেখুন http://en.wikedia.org/wiki/Recursion_( কম্পিউটার কম্পিউটার_সায়েন্স)) আমরা এমন পরিস্থিতিতে রয়েছি যা অসীম পুনরাবৃত্তি হিসাবে পরিচিত এবং আমরা কল স্ট্যাকের মধ্যে যুক্তিগুলি এবং ফেরতের ঠিকানাটি পাইল করে রাখি। যেহেতু কল স্ট্যাক আকারে সীমাবদ্ধ, আমরা অবশেষে স্থানের বাইরে চলে গেলাম। কল স্ট্যাকের জায়গার বাইরে চলে যাওয়া ওভারফ্লো হিসাবে পরিচিত। এটি কারণ আমরা আমাদের চেয়ে বেশি স্ট্যাক স্পেস ব্যবহার করার চেষ্টা করছি এবং ডেটা আক্ষরিকভাবে স্ট্যাকটিকে উপচে ফেলেছে। জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজে, এটি রানটাইম ব্যতিক্রম java.lang.StackOver প্রবাহের ফলস্বরূপ এবং প্রোগ্রামটি তত্ক্ষণাত বন্ধ করে দেবে।
উপরের উদাহরণটি কিছুটা সরল করা হয়েছে (যদিও এটি আমি স্বীকার করতে চাইছি তার চেয়ে বেশি আমার ক্ষেত্রে ঘটে। যাইহোক, সাধারণভাবে, স্ট্যাক ওভারফ্লো সাধারণত একবার সমাধান করা বেশ সহজ once
তত্ত্বগতভাবে, পুনরাবৃত্তি ছাড়াই স্ট্যাকের ওভারফ্লো হওয়াও সম্ভব, তবে বাস্তবে এটি মোটামুটি বিরল ঘটনা বলে মনে হবে।
java.lang.StackOverflowError
ত্রুটি java.lang.StackOverflowError
নির্দেশ করে অ্যাপ্লিকেশনের স্ট্যাক ক্লান্ত ছিল, গভীর পুনরাবৃত্তির কারণে অর্থাত আপনার প্রোগ্রাম / স্ক্রিপ্ট খুব গভীরভাবে recurses ফেলে দেওয়া হয়।
StackOverflowError
প্রসারিত VirtualMachineError
বর্গ যা নির্দেশ করে যে জেভিএম হয়েছে বা রিসোর্সের সমাপ্ত করে ফেলেছেন এবং আরও চালনা করতে পারেন না। VirtualMachineError
যা প্রসারিত Error
বর্গ ঐ গুরুতর সমস্যা নির্দেশ করে একটি আবেদন ধরতে করা উচিত নয় ব্যবহার করা হয়। কোনও পদ্ধতি তার throw
অনুচ্ছেদে এ জাতীয় ত্রুটিগুলি ঘোষণা করতে পারে না কারণ এই ত্রুটিগুলি অস্বাভাবিক পরিস্থিতি যা কখনই ঘটবে বলে আশা করা যায়নি।
Minimal, Complete, and Verifiable Example
:
package demo;
public class StackOverflowErrorExample {
public static void main(String[] args)
{
StackOverflowErrorExample.recursivePrint(1);
}
public static void recursivePrint(int num) {
System.out.println("Number: " + num);
if(num == 0)
return;
else
recursivePrint(++num);
}
}
Number: 1
Number: 2
.
.
.
Number: 8645
Number: 8646
Number: 8647Exception in thread "main" java.lang.StackOverflowError
at java.io.FileOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.flushBuffer(Unknown Source)
at java.io.OutputStreamWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.newLine(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:11)
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
.
.
.
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
যখন কোনও জাভা অ্যাপ্লিকেশন দ্বারা কোনও ফাংশন কল শুরু করা হয়, কল স্ট্যাকের উপর একটি স্ট্যাক ফ্রেম বরাদ্দ করা হয় । আমন্ত্রিত পদ্ধতির প্যারামিটারগুলি, এর স্থানীয় প্যারামিটারগুলি এবং পদ্ধতির রিটার্ন ঠিকানা রয়েছে The প্রত্যাবর্তনের ঠিকানাটি কার্যকর করা পয়েন্টটিকে বোঝায় যা থেকে, প্রোগ্রামটি কার্যকর করা অনুরোধকৃত পদ্ধতিটি ফিরে আসার পরে চলতে থাকবে। যদি কোনও নতুন স্ট্যাক ফ্রেমের জন্য জায়গা না থাকে তবে জাভা ভার্চুয়াল মেশিন (জেভিএম) নিক্ষেপ করে।stack frame
StackOverflowError
সম্ভবত একটি জাভা অ্যাপ্লিকেশনটির স্ট্যাককে নিঃশেষিত করতে পারে এমন সাধারণ ঘটনাটি পুনরাবৃত্তি। পুনরাবৃত্তি হিসাবে, একটি পদ্ধতি তার প্রয়োগের সময় নিজেকে ডাকে। Recursion
অন্যতম শক্তিশালী সাধারণ উদ্দেশ্যে প্রোগ্রামিং কৌশল, তবে StackOverflowError
এড়াতে যাতে সতর্কতার সাথে ব্যবহার করতে হয়।
যখন কোনও জাভা অ্যাপ্লিকেশন দ্বারা কোনও ফাংশন কল শুরু করা হয়, কল স্ট্যাকের উপর একটি স্ট্যাক ফ্রেম বরাদ্দ করা হয়। স্ট্যাক ফ্রেমে আমন্ত্রিত পদ্ধতির প্যারামিটারগুলি, এর স্থানীয় পরামিতিগুলি এবং পদ্ধতির ফেরতের ঠিকানা রয়েছে।
প্রত্যাবর্তনের ঠিকানাটি কার্যকর হওয়া পয়েন্টটিকে বোঝায় যা থেকে, প্রোগ্রামটি কার্যকর করা অনুরোধকৃত পদ্ধতিটি ফিরে আসার পরে চলতে থাকবে। যদি কোনও নতুন স্ট্যাক ফ্রেমের জন্য জায়গা না থাকে তবে স্ট্যাকওভারফ্লো ইয়ারকে জাভা ভার্চুয়াল মেশিন (জেভিএম) দ্বারা নিক্ষেপ করা হবে ।
সম্ভবত একটি জাভা অ্যাপ্লিকেশনটির স্ট্যাককে নিঃশেষিত করতে পারে এমন সাধারণ ঘটনাটি পুনরাবৃত্তি।
তাকাও এখানে
হাইপারনেট ব্যবহারকারীদের জন্য ডেটা পার্স করার সময় সমাধান:
আমার এই ত্রুটি হয়েছিল কারণ আমি উভয় পক্ষের ম্যাপযুক্ত অবজেক্টগুলির একটি তালিকা পার্স করছিলাম @OneToMany
এবং @ManyToOne
জ্যাকসন ব্যবহার করে জসন যা একটি অসীম লুপ তৈরি করেছিল caused
আপনি যদি একই পরিস্থিতিতে থাকেন তবে আপনি এটি ব্যবহার করে @JsonManagedReference
এবং @JsonBackReference
টীকা দ্বারা সমাধান করতে পারেন ।
এপিআই থেকে সংজ্ঞা:
জসনম্যানেজডরেফারেন্স ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonManagedReferences.html ):
টীকাগত সম্পত্তিটি ক্ষেত্রগুলির মধ্যে দ্বি-মুখী সংযোগের একটি অংশ হিসাবে চিহ্নিত করতে ব্যবহৃত টিকা; এবং এর ভূমিকাটি "পিতামাতার" (বা "ফরোয়ার্ড") লিঙ্ক। সম্পত্তির মান ধরণের (শ্রেণি) জাসনব্যাক রেফারেন্স সহ একটি একক সামঞ্জস্যপূর্ণ সম্পত্তি থাকতে হবে। লিঙ্কেজটি এমনভাবে পরিচালনা করা হয় যে এই টীকায় বিশিষ্ট সম্পত্তিটি সাধারণত পরিচালনা করা হয় (সাধারণত সিরিয়ালযুক্ত করা হয়, ডিসিরিয়ালেসনের জন্য কোনও বিশেষ পরিচালনা নেই); এটি ম্যাচিং ব্যাক রেফারেন্সের জন্য বিশেষ হ্যান্ডলিংয়ের প্রয়োজন
জসনব্যাক রেফারেন্স: ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonBackReferences.html ):
সংযুক্ত সম্পত্তি ক্ষেত্রের মধ্যে দ্বি-মুখী সংযোগের অংশ এটি ইঙ্গিত করার জন্য ব্যবহৃত টীকা; এবং এর ভূমিকাটি "শিশু" (বা "পিছনে") লিঙ্ক। সম্পত্তির মান ধরণের অবশ্যই একটি শিম হতে হবে: এটি সংগ্রহ, মানচিত্র, অ্যারে বা গণনা হতে পারে না। লিঙ্কেজ এমনভাবে পরিচালনা করা হয় যে এই টীকায় সম্পত্তি দ্বারা টীকাগুলি ক্রমিকায়িত হয় না; এবং deserialization সময়, এর মান উদাহরণস্বরূপ সেট করা হয় যে "পরিচালিত" (ফরোয়ার্ড) লিঙ্ক আছে।
উদাহরণ:
মালিক.জভা:
@JsonManagedReference
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
Set<Car> cars;
কার.জাভা:
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;
আরেকটি সমাধান হ'ল ব্যবহারটি @JsonIgnore
যা ক্ষেত্রের জন্য কেবল শূন্য করবে।
হাইবারনেট দিয়ে আমি একটি প্রোগ্রাম তৈরি করেছি, যেখানে আমি দুটি পজো ক্লাস তৈরি করেছিলাম, উভয়ই একে অপরের সাথে ডেটা মেম্বার হিসাবে an মূল পদ্ধতিতে যখন আমি তাদের ডাটাবেসে সংরক্ষণ করার চেষ্টা করেছি তখন আমি এই ত্রুটিটি পেয়েছি।
এটি ঘটেছিল কারণ উভয় শ্রেণিই একে অপরকে রেফার করছে, অতএব একটি লুপ তৈরি করছে যা এই ত্রুটি ঘটায়।
সুতরাং, আপনার প্রোগ্রামে এই জাতীয় কোনও সম্পর্ক বিদ্যমান কিনা তা পরীক্ষা করে দেখুন।
স্ট্রাকের ওভারফ্লো ব্যতিক্রমগুলি ঘটতে পারে যখন কোনও থ্রেড স্ট্যাক সর্বাধিক সীমাতে পৌঁছানো পর্যন্ত আকারে বাড়তে থাকে।
স্ট্যাকের আকারগুলি (এক্সএসএস এবং এক্সএমএসো) বিকল্পগুলি সমন্বয় করা হচ্ছে ...
আমি আপনাকে এই লিঙ্কটি দেখার পরামর্শ দিচ্ছি: http://www-01.ibm.com/support/docview.wss?uid=swg21162896 স্ট্যাকওভারফ্লো এররের অনেকগুলি সম্ভাব্য কারণ রয়েছে, যেমন আপনি লিঙ্কটিতে দেখতে পারেন ....
আমার ক্ষেত্রে আমার দুটি কার্যক্রম রয়েছে। দ্বিতীয় ক্রিয়াকলাপে আমি অনক্রিট পদ্ধতিতে সুপার লাগাতে ভুলে গিয়েছিলাম।
super.onCreate(savedInstanceState);
StackOverflowError
আমি এই প্রশ্নের উত্তর দিচ্ছি তা কিছু নয়। আমি মনে করি একটি যথাযথ উত্তরের সাথে এই ব্যতিক্রমটি পাওয়ার জন্য অন্যান্য উপায়গুলির তালিকা থাকা উচিত যা খুব বেশি সংখ্যক পুনরাবৃত্তি ব্যবহার না করে বা বলা উচিত যে ম্যানুয়ালি নিক্ষেপ করা ছাড়া এ জাতীয় ব্যতিক্রম পাওয়ার কোনও উপায় অবশ্যই নেই।