জাভাতে স্ট্যাক এবং হিপ মেমরি


99

আমি যেমন বুঝতে পেরেছি, জাভাতে, স্ট্যাক মেমরিটি আদিম এবং পদ্ধতি আমন্ত্রণ রাখে এবং হ্যাপ মেমরিটি বস্তুগুলি সঞ্চয় করতে ব্যবহৃত হয়।

ধরুন আমার একটা ক্লাস আছে

class A {
       int a ;
       String b;
       //getters and setters
}
  1. aক্লাসে আদিম কোথায় রাখা হবে A?

  2. হিপ মেমরি কেন আদৌ বিদ্যমান? আমরা কেন স্ট্যাকের সব কিছু সংরক্ষণ করতে পারি না?

  3. যখন বস্তুটি আবর্জনা সংগ্রহ করা হয়ে যায়, আপত্তিযুক্তগুলির সাথে স্ট্যাকটি কী ধ্বংস হয়?


1
stackoverflow.com/questions/1056444/is-it-on-the-stack-or-heap আপনার প্রশ্নের উত্তর বলে মনে হচ্ছে।
এস .লট

@ এস.লোট, বাদে এইটি জাভা সম্পর্কে, সি নয়
পিটার টারিক

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

9
@ স্টিভেহাইগ: এই সাইটে, সবাই এখানে কিছু আছে কিনা তা নিয়ে খুব উদ্বিগ্ন ... আমি অবাক হচ্ছি যে প্রশ্নগুলি এখানেই আছে কি না তা নিয়ে এই সাইটটি আসলেই কী মাইন্ডশায়ার করছে all
স্যাম গোল্ডবার্গ

উত্তর:


106

স্ট্যাক এবং গাদা মধ্যে মূল পার্থক্য হ'ল মূল্যবোধের জীবনচক্র।

স্ট্যাক মানগুলি কেবলমাত্র সেগুলিতে তৈরি করা ফাংশনের স্কোপের মধ্যেই বিদ্যমান Once এটি একবার ফিরে আসার পরে সেগুলি বাতিল করে দেওয়া হবে।
স্তূপে গাদা মানগুলি বিদ্যমান on এগুলি কোনও এক সময় তৈরি করা হয় এবং অন্য সময়ে ধ্বংস হয় (জিসি দ্বারা বা ম্যানুয়ালি ভাষা / রানটাইমের উপর নির্ভর করে)।

এখন জাভা কেবল স্টেমের মধ্যে আদিমগুলিকে সঞ্চয় করে। এটি স্ট্যাকটি ছোট রাখে এবং স্বতন্ত্র স্ট্যাক ফ্রেমগুলি ছোট রাখতে সহায়তা করে, এইভাবে আরও নীচে কল করার অনুমতি দেয়।
বস্তুগুলি স্তূপে তৈরি করা হয়, এবং কেবলমাত্র রেফারেন্সগুলি (যা পরিবর্তে আদিম হয়) স্ট্যাকের চারপাশে পাস করা হয়।

সুতরাং আপনি যদি কোনও বস্তু তৈরি করেন তবে এটি তার সাথে সম্পর্কিত সমস্ত ভেরিয়েবলগুলির সাথে এটি গাদাতে রাখা হয়, যাতে এটি ফাংশন কলের রিটার্নের পরেও স্থির থাকতে পারে।


2
"এবং কেবলমাত্র রেফারেন্স (যা পরিবর্তে আদিম হয়)" কেন বলে যে রেফারেন্সগুলি আদিম? আপনি দয়া করে পরিষ্কার করতে পারেন?
গিক

5
@ গীক: যেহেতু আদিম ডেটা ধরণের সাধারণ সংজ্ঞা প্রয়োগ হয়: "একটি প্রোগ্রামিং ভাষার দ্বারা একটি বেসিক বিল্ডিং ব্লক হিসাবে সরবরাহ করা একটি ডেটা টাইপ" । আপনি আরও খেয়াল করতে পারেন যে নিবন্ধে আরও নীচে বর্ণিত উদাহরণগুলির মধ্যে রেফারেন্সগুলি তালিকাভুক্ত রয়েছে ।
back2dos

4
@ গীক: তথ্যের নিরিখে, আপনি যে কোনও আদিম উপাত্তের প্রকার - রেফারেন্স সহ - সংখ্যা হিসাবে দেখতে পারেন। এমনকি charগুলি সংখ্যার হয় এবং একে অপরের পরিবর্তে ব্যবহার করা যেতে পারে। রেফারেন্সগুলি কেবলমাত্র 32 বা 64 বিট লম্বা মেমরি ঠিকানার উল্লেখ করে কেবল সংখ্যাগুলি (যদিও এগুলি ব্যবহার করা যায় না - যদি না আপনি চারপাশে গোলযোগ করছেন sun.misc.Unsafe)।
সুন রাসমুসেন

3
এই উত্তরের পরিভাষাটি ভুল। জাভা ভাষার স্পেসিফিকেশন অনুসারে, উল্লেখগুলি আদিম নয়। উত্তরগুলি যা বলে তার সংক্ষিপ্তসার যদিও সঠিক। (আপনি একটি আর্গুমেন্ট যে রেফারেন্স হল "একটি অর্থে" করতে পারেন যদিও আদিম দ্বারা হয় JLS জাভা জন্য পরিভাষা সংজ্ঞায়িত, এবং এটি বলছে যে আদিম ধরনের হয়। boolean, byte, short, char, int, long, floatএবং double।)
স্টিফেন সি

4
যেমনটি আমি এই নিবন্ধটিতে পেয়েছি , জাভা স্ট্যাকগুলিতে বস্তুগুলি সংরক্ষণ করতে পারে (বা এমনকি ছোট স্বল্পস্থায়ী বস্তুর নিবন্ধগুলিতেও)। জেভিএম কভারগুলির নীচে বেশ কিছুটা করতে পারে। এটি বলা ঠিক ঠিক নয় "এখন জাভা কেবল স্ট্যাকের মধ্যে আদিমগুলি সঞ্চয় করে।"

49

আদিম ক্ষেত্রগুলি কোথায় সংরক্ষণ করা হয়?

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

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

সুতরাং, "অবজেক্টটি তৈরি হয় এবং ক্ষেত্রটিও সেখানে রয়েছে" বলার বাইরে কিছু গাদা বা স্ট্যাকের উপর থাকলে কেউ বলতে পারে না। মনে রাখবেন যে ছোট, স্বল্প জীবিত অবজেক্টের জন্য এটি সম্ভবত সম্ভব যে 'বস্তু' স্মৃতিতে উপস্থিত থাকবে না এবং এর পরিবর্তে এর ক্ষেত্রগুলি সরাসরি রেজিস্টারগুলিতে স্থাপন করা যেতে পারে।

কাগজটি দিয়ে শেষ হয়েছে:

JVM গুলি আশ্চর্যজনকভাবে এমন জিনিসগুলি নির্ধারণ করতে পারে যা আমরা ধরে নিই যে কেবল বিকাশকারীই জানতে পারে। জেভিএম কেস-কেস-কেস ভিত্তিতে স্ট্যাক বরাদ্দ এবং হিপ বরাদ্দের মধ্যে চয়ন করতে দিয়ে আমরা প্রোগ্রামারটিকে স্ট্যাকের বা স্তূপে বরাদ্দ দেওয়ার বিষয়ে উদ্বেগ তৈরি না করে স্ট্যাক বরাদ্দের পারফরম্যান্স সুবিধা পেতে পারি।

সুতরাং, আপনার কাছে এমন কোড রয়েছে যা দেখতে দেখতে:

void foo(int arg) {
    Bar qux = new Bar(arg);
    ...
}

যেখানে সুযোগটি ছাড়তে ...দেয় না qux, তার পরিবর্তে স্ট্যাকের জন্য বরাদ্দ দেওয়া qux যেতে পারে। এটি আসলে ভিএম এর জন্য একটি জয় কারণ এর অর্থ এটি কখনই আবর্জনা সংগ্রহ করার দরকার নেই - সুযোগ ছাড়লে এটি অদৃশ্য হয়ে যায়।

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

স্ট্যাক এবং গাদা হ'ল

গাদা

তাহলে, কেন স্ট্যাক বা গাদাটি একেবারে আছে? যে জিনিসগুলি সুযোগ ছেড়ে দেয়, তাদের জন্য স্ট্যাকটি ব্যয়বহুল হতে পারে। কোডটি বিবেচনা করুন:

void foo(String arg) {
    bar(arg);
    ...
}

void bar(String arg) {
    qux(arg);
    ...
}

void qux(String arg) {
    ...
}

পরামিতিগুলিও স্ট্যাকের একটি অংশ। আপনার কাছে কোনও গাদা নেই এমন পরিস্থিতিতে আপনি স্ট্যাকের উপর পূর্ণ মানগুলি পাস করবেন। এটি "foo"ছোট এবং ছোট স্ট্রিংগুলির জন্য ঠিক আছে ... তবে কেউ যদি স্ট্রিংটিতে একটি বিশাল এক্সএমএল ফাইল রাখে তবে কি হবে। প্রতিটি কল স্ট্যাকের উপরে পুরো বিশাল স্ট্রিংটি অনুলিপি করবে - এবং এটি যথেষ্ট অপব্যয় হবে।

পরিবর্তে, অবিলম্বে সুযোগের বাইরে কিছু জিনিস থাকা বস্তুগুলিকে (অন্য স্কোপে চলে গেছে, এমন কাঠামোর মধ্যে আটকে আছে যা অন্য কেউ রক্ষণাবেক্ষণ করছে, ইত্যাদি ...) অন্য একটি অঞ্চলে রেখে দেওয়া ভাল যা হিপ বলা হয়।

স্ট্যাকের উপর

আপনি না প্রয়োজন স্ট্যাক। হাইপোথটিকালি কেউ এমন একটি ভাষা লিখতে পারেন যা স্ট্যাক ব্যবহার করে না (স্বেচ্ছাসেবী গভীরতার)। একটি পুরানো বেসিক যা আমি আমার যৌবনে শিখেছি তা করেছে, একজন কেবল মাত্র 8 স্তরের gosubকল করতে পারে এবং সমস্ত ভেরিয়েবলগুলি বিশ্বব্যাপী ছিল - কোনও স্ট্যাক ছিল না।

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

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

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

যখন কিছু আবর্জনা সংগ্রহ করা হয়

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

আমি উল্লেখ করব যে এটি আবর্জনা সংগ্রহের খুব বড় সরলকরণ। অনেকগুলি আবর্জনা সংগ্রহকারী (এমনকি জাভার মধ্যেও - আপনি বিভিন্ন পতাকা ( ডকস ) ব্যবহার করে আবর্জনা সংগ্রহকারীকে কল করতে পারেন These এগুলি আলাদাভাবে আচরণ করে এবং প্রত্যেকে কীভাবে কাজ করে তার সংক্ষিপ্ততা এই উত্তরের জন্য কিছুটা গভীর। আপনি পড়তে ইচ্ছুক হতে পারেন জাভা আবর্জনা সংগ্রহের মূল বিষয়গুলি এর মধ্যে কীভাবে কাজ করে সে সম্পর্কে আরও ভাল ধারণা পেতে।

এটি বলেছিল, যদি স্ট্যাকের জন্য কিছু বরাদ্দ করা হয়, তবে এটি অংশ হিসাবে সংগ্রহ করা আবর্জনা নয় System.gc()- স্ট্যাক ফ্রেমটি পপ হওয়ার পরে এটি নির্বিঘ্নিত হয়। যদি কিছু গাদা থাকে এবং স্ট্যাকের কোনও কিছু থেকে রেফারেন্স করা হয়, তবে এটি সেই সময়ে সংগ্রহ করা আবর্জনা হবে না।

কেন এই ব্যাপার?

বেশিরভাগ অংশে, এটির .তিহ্য। লিখিত পাঠ্য বই এবং সংকলক ক্লাস এবং বিভিন্ন বিট ডকুমেন্টেশন হিপ এবং স্ট্যাক সম্পর্কে একটি বড় চুক্তি করে।

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

অবজেক্টটি কোথাও এবং এটির জায়গায় যেখানে এটি উপস্থিত থাকা উপযুক্ত সময়ের জন্য সঠিকভাবে এবং দ্রুত অ্যাক্সেস করা যায়। যদি এটি স্ট্যাক বা গাদাতে থাকে - এটি আসলে কোনও ব্যাপার নয়।


7
  1. স্তূপে, অবজেক্টের অংশ হিসাবে, যা স্ট্যাকের একটি পয়েন্টার দ্বারা রেফারেন্স করা হয়। অর্থাত। a এবং b একে অপরের সংলগ্ন সংরক্ষণ করা হবে।
  2. কারণ যদি সমস্ত স্মৃতি মেমরি স্ট্যাক থাকে তবে এটি আর দক্ষ হবে না। একটি ছোট, দ্রুত অ্যাক্সেসের অঞ্চল থাকা ভাল যেখানে আমরা শুরু করি এবং মেমরির অনেক বৃহত্তর অঞ্চলে সেই রেফারেন্স আইটেমগুলি পাওয়া যায়। যাইহোক, এটি অত্যধিক কিল হয় যখন কোনও বস্তু কেবলমাত্র একক আদিম হয় যা স্ট্যাকের পয়েন্টার হিসাবে একই পরিমাণে স্থান গ্রহণ করে।
  3. হ্যাঁ.

1
আমি আপনার পয়েন্ট # 2 এ যুক্ত করব যে আপনি যদি স্ট্যাকের উপর বস্তুগুলি সঞ্চিত করেন (কয়েক হাজার এন্ট্রি সহ একটি অভিধানের বিষয়টি কল্পনা করুন) তবে এটি কোনও ফাংশনে পাস করার জন্য বা ফেরত দেওয়ার জন্য আপনাকে প্রতিটি বস্তুর অনুলিপি করতে হবে সময়। হিপগুলির মধ্যে কোনও পয়েন্টার বা রেফারেন্স ব্যবহার করে আমরা কেবল (ছোট) রেফারেন্সটি পাস করি।
স্কট হুইটলক

1
আমি ভেবেছিলাম 3 টি 'না' হবে কারণ যদি বস্তুটি আবর্জনা-সংগ্রহ করা হচ্ছে, তবে এটির দিকে নির্দেশ করে স্ট্যাকের কোনও রেফারেন্স নেই।
লুসিয়ানো

@ লুসিয়ানো - আমি আপনার বক্তব্যটি দেখতে পাচ্ছি আমি প্রশ্ন 3 ভিন্নভাবে পড়তে। "একই সময়ে" বা "সেই সময়ের মধ্যে" অন্তর্ভুক্ত। :: শ্রাগ ::
পিডিআর

3
  1. জাভা যখন অব্যাহতি বিশ্লেষণের মাধ্যমে প্রমাণ করে যে এটি শব্দার্থকে প্রভাবিত করবে না তারপরে একটি অপ্টিমাইজেশন হিসাবে স্ট্যাকের উপর ক্লাস উদাহরণ বরাদ্দ না করে স্তূপে। এটি বাস্তবায়নের বিশদ, যদিও মাইক্রো-অপ্টিমাইজেশান ব্যতীত অন্যান্য সমস্ত ব্যবহারিক উদ্দেশ্যে উত্তরটি হ'ল "গাদাতে"।

  2. স্ট্যাক মেমরি অবশ্যই শেষ বরাদ্দ করতে হবে এবং শেষের দিকে ডিলোক্যাট করা উচিত। হ্যাপ মেমরি বরাদ্দ এবং যে কোনও ক্রমে dellocated করা যেতে পারে।

  3. যখন অবজেক্টটি আবর্জনা সংগ্রহ করা হয়, তখন স্ট্যাক থেকে এটি দেখানোর মতো আরও কোনও রেফারেন্স নেই। যদি সেখানে থাকত তবে তারা বস্তুটি বাঁচিয়ে রাখতে চাইবে। স্ট্যাক আদিমগুলি আবর্জনা আদৌ সংগ্রহ করা হয় না কারণ ফাংশন ফিরে আসার সাথে সাথে সেগুলি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায়।


3

স্ট্যাক মেমরি স্থানীয় ভেরিয়েবল এবং ফাংশন কল সঞ্চয় করতে ব্যবহৃত হয়।

জাভাতে বস্তু সংরক্ষণের জন্য হিপ মেমরি ব্যবহৃত হয়। কোনও বিষয় নয়, যেখানে কোডে অবজেক্ট তৈরি করা হয়েছে।

কোথায় আদিম হবে aমধ্যে class Aসংরক্ষণ করা?

এক্ষেত্রে আদিম ক শ্রেণীর A অবজেক্টের সাথে সম্পর্কিত। সুতরাং এটি হিপ মেমোরিতে তৈরি করে।

হিপ মেমরি কেন আদৌ বিদ্যমান? আমরা কেন স্ট্যাকের সব কিছু সংরক্ষণ করতে পারি না?

  • স্ট্যাকের উপর তৈরি ভেরিয়েবলগুলি সুযোগের বাইরে চলে যাবে এবং স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যাবে।
  • স্তূপে ভেরিয়েবলের তুলনায় বরাদ্দ করতে স্ট্যাকটি আরও দ্রুত।
  • স্তূপে থাকা ভেরিয়েবলগুলি অবশ্যই আবর্জনা সংগ্রহকারী দ্বারা ধ্বংস করতে হবে।
  • স্ট্যাকের ভেরিয়েবলের সাথে তুলনায় তুলনামূলকভাবে ধীর গতিতে।
  • সংকলনের সময় আপনাকে ঠিক কতটা ডেটা বরাদ্দ করতে হবে তা সঠিকভাবে জানা থাকলে এবং এটি খুব বেশি বড় নয় ((স্ট্যাকের আদিম স্থানীয় ভেরিয়েবল স্টোর)
  • রান-টাইমে আপনার ঠিক কতটা ডেটা লাগবে বা আপনার যদি প্রচুর ডেটা বরাদ্দ করতে হয় তবে আপনি সঠিকভাবে জানেন না তবে আপনি হিপটি ব্যবহার করবেন।

যখন বস্তুটি আবর্জনা সংগ্রহ করা হয়ে যায়, আপত্তিযুক্তগুলির সাথে স্ট্যাকটি কী ধ্বংস হয়?

আবর্জনা সংগ্রাহক হিপ মেমরির ক্ষেত্রের অধীনে কাজ করে, সুতরাং এটি এমন বস্তুগুলিকে ধ্বংস করে যা রেট থেকে রেফারেন্সের চেইন নেই having


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