অন্যান্য উত্তরগুলির পাশাপাশি, আমি যুক্ত করতে চাই যে স্ট্যাক এবং হিপ স্পেসের মধ্যে র্যাম তৈরি করার সময়, আপনাকে স্ট্যাটিক অ ধ্রুবক ডেটার জন্যও স্থান বিবেচনা করতে হবে (যেমন ফাইল গ্লোবাল, ফাংশন স্ট্যাটিক্স এবং প্রোগ্রাম-ওয়াইড সি দৃষ্টিকোণ থেকে গ্লোবালগুলি এবং সি ++ এর জন্য সম্ভবত অন্যরা)।
কীভাবে স্ট্যাক / গাদা বরাদ্দ কাজ করে
এটি লক্ষণীয় যে স্টার্টআপ সমাবেশ ফাইলটি অঞ্চলটিকে সংজ্ঞায়নের এক উপায়; টুলচেন (আপনার বিল্ড এনভায়রনমেন্ট এবং রান-টাইম এনভায়রনমেন্ট উভয়ই) বেশিরভাগ প্রতীকগুলিকে যত্ন করে যা স্ট্যাকস্পেসের সূচনা (ভেক্টর টেবিলের মধ্যে প্রাথমিক স্ট্যাক পয়েন্টার সংরক্ষণের জন্য ব্যবহৃত হয়) এবং হিপ স্পেসের শুরু এবং শেষ (গতিশীল দ্বারা ব্যবহৃত) মেমরি বরাদ্দকারী, সাধারণত আপনার libc দ্বারা সরবরাহ করা হয়)
ওপি-র উদাহরণে, কেবল 2 টি প্রতীক সংজ্ঞায়িত করা হয়, 1kiB তে স্ট্যাকের একটি আকার এবং 0 বি তে একটি আকারের। এই মানগুলি স্ট্যাক এবং হিপ স্পেসগুলি তৈরি করতে অন্য কোথাও ব্যবহৃত হয়
@ গিলস উদাহরণে, আকারগুলি স্ট্যাক_মিমে প্রতীক দ্বারা চিহ্নিত এবং আকার স্থায়ীভাবে স্থায়ীভাবে সেট করার জন্য অ্যাসেম্বলি ফাইলটিতে সংজ্ঞায়িত এবং ব্যবহৃত হয় এবং শেষে __initial_sp একটি লেবেল সেট করে। অনুরূপভাবে স্তূপের জন্য, যেখানে স্থানটি হিপ_মিম (আকারে 0.5KB) প্রতীক, তবে শুরু এবং শেষের লেবেল সহ (__heap_base এবং __heap_limit)।
এগুলি লিঙ্কারের মাধ্যমে প্রক্রিয়াজাত হয়, যা স্ট্যাক স্পেস এবং হিপ স্পেসের মধ্যে কোনও কিছুই বরাদ্দ দেয় না কারণ সেই স্মৃতিটি দখল করা আছে (স্ট্যাক_মেম এবং হিপ_মিম চিহ্ন দ্বারা) তবে এটি সেই স্মৃতিগুলি এবং সমস্ত গ্লোবাল যেখানেই এটি প্রয়োজন সেখানে স্থাপন করতে পারে। লেবেলগুলি প্রদত্ত ঠিকানাগুলিতে দৈর্ঘ্য ছাড়াই প্রতীক হিসাবে শেষ হয়। __Initial_sp লিংক সময়ে সরাসরি ভেক্টর টেবিলের জন্য এবং আপনার রানটাইম কোড দ্বারা __heap_base এবং __heap_limit ব্যবহার করা হয়। চিহ্নগুলির প্রকৃত ঠিকানাগুলি লিঙ্কার যেখানে স্থাপন করেছিল তার উপর ভিত্তি করে নির্ধারিত হয়।
আমি উপরে জোর দিয়েছি, এই চিহ্নগুলি আসলে একটি স্টার্টআপ.স ফাইল থেকে আসে না। এগুলি আপনার লিঙ্কার কনফিগারেশন (কেইলে স্ক্যাটার লোড ফাইল, জিএনইউতে লিংস্ক্রিপ্ট) থেকে আসতে পারে এবং সেগুলির মধ্যে আপনার বসানো উপর সূক্ষ্ম দানাদার নিয়ন্ত্রণ থাকতে পারে। উদাহরণস্বরূপ, আপনি স্ট্যাকটি রামের শুরুতে বা শেষ হতে বাধ্য করতে পারেন, বা আপনার গ্লোবালগুলি গাদা থেকে দূরে রাখতে পারেন, বা যা আপনি চান। এমনকি আপনি উল্লেখ করতে পারেন যে গ্লোবাল স্থাপনের পরে যে পরিমাণ র্যাম র্যাম বাকি আছে কেবল হিপ বা স্ট্যাক কেবল দখল করে। উল্লেখ্য যে আপনার অন্যান্য স্মৃতি হ্রাস পাবে এমন স্থিতিশীল ভেরিয়েবল যুক্ত করার ক্ষেত্রে আপনাকে সতর্ক থাকতে হবে।
তবে, প্রতিটি সরঞ্জামচইন আলাদা এবং কনফিগারেশন ফাইলটি কীভাবে লিখবেন এবং আপনার গতিশীল মেমরির বরাদ্দকারী কী চিহ্ন ব্যবহার করবে তা আপনার নির্দিষ্ট পরিবেশের ডকুমেন্টেশন থেকে আসতে হবে।
স্ট্যাক সাইজিং
স্ট্যাকের আকার কীভাবে নির্ধারণ করা যায় সে বিষয়ে অনেক সরঞ্জামচেন আপনার প্রোগ্রামের ফাংশন কল ট্রিগুলি বিশ্লেষণ করে আপনাকে সর্বাধিক স্ট্যাকের গভীরতা দিতে পারে, যদি আপনি পুনরাবৃত্তি বা ফাংশন পয়েন্টার ব্যবহার না করেন। যদি আপনি সেগুলি ব্যবহার করেন, কোনও স্ট্যাকের আকার অনুমান করে এবং এটি মূল মানগুলি (সম্ভবত প্রধানের আগে প্রবেশের ফাংশন দিয়ে) দিয়ে পূর্বে পূরণ করে এবং তারপরে আপনার প্রোগ্রামটি পরীক্ষা করার পরে সর্বাধিক গভীরতা কোথায় ছিল (যা সেখানে কার্ডিনাল মানগুলি শেষ). আপনি যদি নিজের প্রোগ্রামটির সীমাবদ্ধতার সাথে পুরোপুরি অনুশীলন করে থাকেন তবে আপনি স্ট্যাকটি সঙ্কুচিত করতে পারবেন কিনা বা আপনার প্রোগ্রাম ক্র্যাশ হয়ে গেছে বা কোনও প্রাথমিক মান বাকি আছে কিনা তা আপনি পুরোপুরি সঠিকভাবে জানতে পারবেন যে আপনাকে স্ট্যাকটি বাড়িয়ে আবার চেষ্টা করতে হবে।
হিপ সাইজিং
হ্যাপের আকার নির্ধারণ করা আরও বেশি অ্যাপ্লিকেশন নির্ভর। আপনি যদি প্রারম্ভকালীন সময়ে কেবল গতিশীল বরাদ্দ করেন, আপনি কেবল আপনার স্টার্টআপ কোডে প্রয়োজনীয় স্থানটি যুক্ত করতে পারেন (মেমরি পরিচালনার জন্য কিছু ওভারহেড)। আপনার মেমরি পরিচালকের উত্সটিতে অ্যাক্সেস থাকলে আপনি ওভারহেড কী তা সঠিকভাবে জানতে পারবেন এবং সম্ভবত ব্যবহারের তথ্য দেওয়ার জন্য মেমরিটিতে হাঁটার জন্য কোড লিখতেও পারেন। অ্যাপ্লিকেশনগুলির জন্য যা ডায়নামিক রানটাইম মেমরির প্রয়োজন (উদাহরণস্বরূপ ইনবাউন্ড ইথারনেট ফ্রেমের জন্য বাফার বরাদ্দ করা) আমার পক্ষে সবচেয়ে ভাল পরামর্শ দেওয়া হ'ল সতর্কতার সাথে আপনার স্ট্যাকসাইজ হোন করা এবং স্ট্যাক এবং স্ট্যাটিক্সের পরে যে সমস্ত জিনিস রেখে দেওয়া হয়েছে তা হিপটি দেওয়া।
চূড়ান্ত নোট (আরটিওএস)
ওপির প্রশ্নটি খালি-ধাতুর জন্য ট্যাগ করা ছিল, তবে আমি আরটিওসগুলির জন্য একটি নোট যুক্ত করতে চাই। প্রায়শই (সর্বদা?) প্রতিটি কাজ / প্রক্রিয়া / থ্রেড (সরলতার জন্য আমি কেবল এখানে টাস্কটি লিখব) যখন টাস্কটি তৈরি করা হবে তখন একটি স্ট্যাকের আকার নির্ধারণ করা হবে, টাস্ক স্ট্যাকের পাশাপাশি একটি ছোট ওএস থাকবে স্ট্যাক (বিঘ্ন এবং এই জাতীয় জন্য ব্যবহৃত)
টাস্ক অ্যাকাউন্টিং স্ট্রাকচার এবং স্ট্যাকগুলি কোথাও থেকে বরাদ্দ করতে হবে এবং এটি প্রায়শই আপনার আবেদনের সামগ্রিক স্তূপ স্থান থেকে হবে। এই উদাহরণগুলিতে, আপনার প্রাথমিক স্ট্যাকের আকারটি প্রায়শই কোনও ব্যাপার নয়, কারণ ওএস কেবলমাত্র আরম্ভের সময় এটি ব্যবহার করবে। আমি দেখেছি, উদাহরণস্বরূপ, সংযোগের সময় সমস্ত অবশিষ্ট স্থান নির্দিষ্ট করে হিপকে বরাদ্দ করতে হবে এবং গাদা শেষে প্রারম্ভিক স্ট্যাক পয়েন্টার রেখে গাদা হয়ে উঠতে হবে, জেনেও যে ওএস গাদা শুরু থেকে শুরু করবে এবং প্রাথমিক_এসপি স্ট্যাকটি পরিত্যাগ করার ঠিক আগে ওএস স্ট্যাক বরাদ্দ করবে। তারপরে সমস্ত জায়গাগুলি টাস্ক স্ট্যাকগুলি বরাদ্দকরণ এবং অন্যান্য গতিশীল বরাদ্দ মেমরির জন্য ব্যবহৃত হয়।