সি ++ গেমস কীভাবে মেমরি বরাদ্দ ব্যর্থতা পরিচালনা করে?


23

আমি বেশ কয়েকটি গেম সম্পর্কে সচেতন যা সি ++ তে লেখা আছে তবে ব্যতিক্রমগুলি ব্যবহার করে না। যেহেতু সি ++ তে মেমরি বরাদ্দ ব্যর্থতা হ্যান্ডলিংটি সাধারণত std::bad_allocব্যতিক্রমকে ঘিরে তৈরি করা হয় , এই গেমগুলি এই জাতীয় ব্যর্থতা কীভাবে পরিচালনা করবে?

এগুলি কি কেবল ক্র্যাশ করে, না-মেমরির বাইরে থাকা ত্রুটিটি হ্যান্ডেল করার এবং পুনরুদ্ধার করার কোনও অন্য উপায় আছে?


1
নোট করুন যে এখানে কিছু পরিবেশ / ওএস রয়েছে যেখানে বরাদ্দ সফল বলে দাবি করা হয়েছে, তবে মেমোরিটি ব্যবহার করার চেষ্টা করা আপনার (বা অন্য) প্রোগ্রামটি ক্র্যাশ করে
প্লাজমাএইচএইচ

6
যদি কোনও গেমের সময় বরাদ্দ ব্যর্থ হয় তবে কোয়েস্ট 3 আপনাকে ত্রুটির বার্তা সহ মেনুতে ফিরিয়ে দেবে। আমি বিশ্বাস করি যে এটি সম্ভব হয়েছে কোয়াক 3 এর পুল বরাদ্দকারী দ্বারা, যা পুরো পুলটি ফেলে দিতে পারে এবং পুলটি শেষ হয়ে গেলে নিরাপদে মেনুতে ফিরে আসতে পারে।
ডায়েটারিচ এপ্প

16
সাধারণত ক্রাশ করে
ব্যবহারকারী 253751

1
যদি ব্যতিক্রমগুলি প্রকৃতপক্ষে অক্ষম থাকে তবে প্রোগ্রামটির পরিবর্তে অবশ্যই কল করা উচিত std::terminateএবং এটিই। কিন্তু তারপরে একই বিধিনিষেধের অধীনে বরাদ্দ কোনও ব্যতিক্রম ছোঁড়ার পরিবর্তে নাল পয়েন্টারটি ফিরিয়ে দিতে পারে এবং ফলাফলটি পৃথকভাবে চেক এবং পরিচালনা করা যায়।
আন্ডারস্কোর_ডে

2
সি ++ এ, আপনি বলতে পারেন ClassName variableName = new(nothrow) ClassName();( স্পষ্টতই শ্রেণীর নাম, ভেরিয়েবল নাম ইত্যাদি প্রতিস্থাপন করুন ) তারপরে, যদি বরাদ্দ ব্যর্থ হয়, তবে if(!variableName)চেষ্টা-ব্যতিক্রম ব্যতিক্রম ছাড়াই ত্রুটিটি পরিচালনা করার অনুমতি দিয়ে আপনি এটি সনাক্ত করতে পারবেন । একইভাবে, যদি মেমরি মত একটি ফাংশন ব্যবহার করে বরাদ্দ করা হয় malloc(), calloc()বরাদ্দ করা ব্যর্থতা ইত্যাদি তারপর একই ব্যবহার সনাক্ত করা যাবে if(!variableName)ব্যবহার করে দেখুন-ধরা ছাড়াই পদ্ধতি। গেমগুলি কীভাবে এই ত্রুটিগুলি পরিচালনা করে, ঠিক সেই মুহূর্তে, এটি ক্র্যাশ হয় কিনা তা গেমস নির্ভর করে।
স্পেনসার ডি

উত্তর:


63

সমস্ত গড় প্রোগ্রাম হিসাবে একই: তারা না। *

বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য গ্রাহকের কোনও প্রত্যাশা নেই যে তারা স্মৃতিশক্তি শেষ হয়ে গেলে তারা কাজ চালিয়ে যায়। সমস্ত গেম এই "বেশিরভাগ অ্যাপ্লিকেশন" এর আওতায় পড়ে। প্রান্তের ক্ষেত্রে কাজ করার জন্য সময় এবং অর্থ ব্যয় করা যা গ্রাহক কাজ করার আশা করে না তা বোঝা যায় না।

প্রশ্ন নিম্নলিখিত অনুরূপ:

  • হার্ডডিস্ক পূর্ণ হলে আপনি কীভাবে একটি গেম ইনস্টল করবেন?
  • আপনি এখনও ন্যূনতম চশমা নীচে একটি পিসিতে উচ্চ fps এ গেমটি চালাবেন?

উত্তরটি একই: এটি ব্যবহারকারীর সমস্যা। গেমটি পাত্তা দেয় না।


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


2
: মেমরি অ্যালোকেশন ব্যর্থতার ঘটনা ইত্যাদি লগিং জন্য মেমরি, preallocating উপর stackoverflow.com/questions/7749066/...
bwDraco

23

সাধারণত এই ধরণের পরিস্থিতি কখনই ঘটে না।

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

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

এটি মেমরি ফাঁসের বিরুদ্ধেও সুরক্ষা দেয় কারণ প্রতিটি ছোট ছোট পৃথক বরাদ্দের জন্য ট্র্যাক এবং অ্যাকাউন্ট করার পরিবর্তে, একটি গেম মেমরির পুনরুদ্ধার করতে পুরো পুলটি ফেলে দিতে পারে।

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


3
"পরিবর্তে তারা যা করবে তা হ'ল কেবলমাত্র একবারের শুরুতে মেমরির একটি বড় পুল বরাদ্দ করা এবং যে কোনও রানটাইম বরাদ্দের প্রয়োজন হয় তার জন্য সেই পুল থেকে নেমে আসা" - এবং পুলটি পূর্ণ হলে আপনি কী মনে করেন?
ব্যবহারকারী 253751

@ ইমিবিস - আমার তৃতীয় পয়েন্টটি দেখুন দয়া করে।
ম্যাক্সিমাস মিনিমাস

2
@ ইমিবিস আপনার মানে ... পুলটি খালি থাকলে তারা কী করবে? সিস্টেমের মেমোরি থেকে পৃথক, পুলের আকার এবং ব্যবহার সম্পূর্ণভাবে অ্যাপ্লিকেশনের নিয়ন্ত্রণে। সুতরাং অ্যাপ্লিকেশনটিতে কোনও বাগ না থাকলে পুলটি খালি হয়ে উঠতে পারে না
ডেভিড শোয়ার্টজ

পছন্দ করুন লিনাক্স এটি করে। এমনকি আপনার পুলকে শূন্য করাও যদি zswap বা zram এর মাধ্যমে পেজফাইলে সংক্ষেপণ সক্ষম করে থাকে তবে তা কার্যকর হয় না।
দামিয়ান ইয়ারিক

1
এটি প্রকৃত প্রশ্নের উত্তর বলে মনে হচ্ছে না তবে এর পরিবর্তে "এই জাহাজটি অবিস্মরণীয় তাই আমাদের কীসের জন্য জরুরি প্রক্রিয়া প্রয়োজন?"
লিলিয়েনথাল

2

ওয়েল, প্রধানত, ব্যতিক্রমগুলির অস্তিত্বের আগে আমরা এটি একইভাবে করেছি - পুরাতন "রিটার্ন মান পদ্ধতির পরীক্ষা করুন"। যদি কোনও বরাদ্দকারী ব্যতিক্রম ব্যবহার না করে তবে সাধারণত nullকোনও বরাদ্দ ব্যর্থ হলে এটি ফিরে আসবে । একটি ভাল লিখিত গেমটি এটি পরীক্ষা করে এবং যেভাবেই নিরাপদ পরিস্থিতি পরিচালনা করবে। কখনও কখনও, এর অর্থ গেমটি সমাপ্ত করা (উদাহরণস্বরূপ std::terminate) বা কমপক্ষে সর্বশেষ পরিচিত নিরাপদ অবস্থানে ফিরে যাওয়া (যেমন আপনি যখন কোনও পুল থেকে বরাদ্দ দেন তখন আপনি নিরাপদভাবে পুরো পুলটি নিষ্পত্তি করতে পারেন এমনকি এটি অনিরাপদ অবস্থায় থাকলেও)।

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

মনে মনে, বেশিরভাগ গেমগুলি ক্রাশ হবে। এটি যেমন শোনাচ্ছে তেমন পাগল নয় - আপনার লক্ষ্য হিসাবে সাধারণত কিছু মেমরি ব্যবহার থাকে এবং নিশ্চিত হয়ে নিন যে আপনার গেমটি সেই সীমাতে পৌঁছেছে না (উদাহরণস্বরূপ, আরটিএস গেমের ইউনিট গণনা সীমা ব্যবহার করে বা সীমাবদ্ধ করে কোনও এফপিএসের একটি অংশে শত্রুদের পরিমাণ)। এমনকি যদি আপনি না করেন তবে আপনি সাধারণত কোনও যুক্তিসঙ্গত আধুনিক সিস্টেমে মেমরি হারিয়ে ফেলেন না - উদাহরণস্বরূপ আপনার ভার্চুয়াল অ্যাড্রেস স্পেস (32-বিট অ্যাপ্লিকেশনটিতে) বা স্ট্যাকের বাইরে চলে গেছে। ওএস ইতিমধ্যে ভান করেছে যে আপনি যতটা মেমরি চেয়েছেন তেমন - এটি ভার্চুয়াল মেমরির যে বিমূর্ততা সরবরাহ করে তার মধ্যে একটি। মুল বক্তব্যটি হ'ল আপনার 256 মাইবি দৈহিক র‌্যাম থাকার অর্থ এই নয় যে আপনার অ্যাপ্লিকেশনটি 4 জিবিবি মেমরি ব্যবহার করতে পারে না। কিছু গেম এমনকি খুব বেশি কিছু মনে করতে পারে না যে তাদের সমস্ত ডেটা '


1

একটি ব্যতিক্রম ধরা এবং কখন এবং ব্যতিক্রম উত্থাপিত হয় তা করার সিদ্ধান্ত নেওয়া দুটি ভিন্ন জিনিস।

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

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


ওপি যেমন বলেছে প্রশ্নে থাকা গেমগুলি যদি আক্ষরিক অর্থে "ব্যতিক্রমগুলি ব্যবহার না করে", তবে তারা কোনওটিকে ধরতে, বাড়াতে বা প্রক্রিয়া করতে পারে না। যদি ব্যতিক্রমগুলি অক্ষম থাকে এবং কেউ একটি নিক্ষেপ করে তবে প্রোগ্রামটির পরিবর্তে অবশ্যই কল করা উচিত std::terminateএবং এটিই। তবে এই জাতীয় পরিস্থিতিতে, বরাদ্দ ব্যতিক্রম ছোঁড়ার পরিবর্তে নাল পয়েন্টারটি ফিরিয়ে দিতে পারে এবং এটি আলাদাভাবে পরিচালনা করা যায়।
আন্ডারস্কোর_ডে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.