কেবল উত্স কোড থেকে --- কখন মেমরিটি হ্রাস করতে হবে তা স্থিরভাবে পূর্বাভাস দেওয়া সম্ভব?


27

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

কন্ট্রোল প্রবাহ কার্যকর করা হলে রানটাইমের সময় GC গুলি এটিকে সরাসরি আবিষ্কার করে সমাধান করে। তবে নিয়ন্ত্রণ প্রবাহ সম্পর্কে সত্যের আসল উত্স। সুতরাং তাত্ত্বিকভাবে, free()উত্স (বা এএসটি) বিশ্লেষণ করে সংকলনের আগে কলগুলি কোথায় সন্নিবেশ করা উচিত তা নির্ধারণ করা উচিত ।

রেফারেন্স গণনা এটি বাস্তবায়নের একটি সুস্পষ্ট উপায়, তবে পয়েন্টারগুলি এখনও রেফারেন্সযুক্ত (এখনও সুযোগে) এখনও প্রয়োজন নেই এমন পরিস্থিতিতে পড়ার পক্ষে সহজ। এটি কেবলমাত্র পয়েন্টারগুলিকে ম্যানুয়ালি বিলোপ করার দায়িত্বটিকে সেই পয়েন্টারগুলির ক্ষেত্র / রেফারেন্সগুলি ম্যানুয়ালি পরিচালনা করার জন্য একটি দায়িত্ব হিসাবে রূপান্তর করে।

দেখে মনে হচ্ছে এমন কোনও প্রোগ্রাম লেখা সম্ভব যা কোনও প্রোগ্রামের উত্স পড়তে পারে এবং:

  1. প্রোগ্রামটির নিয়ন্ত্রণ প্রবাহের সমস্ত ক্রিয়াকলাপের পূর্বাভাস --- প্রোগ্রামটির সরাসরি সম্পাদনা দেখার মতো যথার্থতার সাথে
  2. বরাদ্দ সম্পদের সমস্ত রেফারেন্স ট্র্যাক করুন
  3. প্রতিটি রেফারেন্সের জন্য, রেফারেন্সটি কখনও অবহেলিত না হওয়ার গ্যারান্টিযুক্ত এমন প্রথম দিকটি খুঁজে পেতে পুরো পরবর্তী নিয়ন্ত্রণ প্রবাহকে অতিক্রম করুন
  4. এই মুহুর্তে, সোর্স কোডের সেই লাইনে একটি ডিওলোকেশন স্টেটমেন্ট .োকান

এর বাইরে এমন কিছু আছে যা ইতিমধ্যে এটি করে? আমি মনে করি না মরিচা বা সি ++ স্মার্ট পয়েন্টার / আরআইআই একই জিনিস।


57
থামার সমস্যাটি দেখুন এটা কেন দাদাদের প্রশ্ন "কোনও প্রোগ্রাম এক্স করে যদি একটি সংকলক বের করতে পারে না?" সর্বদা "সাধারণ ক্ষেত্রে নয়" দিয়ে উত্তর দেওয়া হয়।
র‌্যাচেট ফ্রিক

18
কোনও প্রোগ্রাম প্রয়োগের সময় মেমরি (এবং রিসোর্স লকগুলি) ডিস্টিস্টিনিস্টিক পয়েন্টগুলিতে ওএস-এ ফিরে আসে। নং
ইউফোরিক

9
@ratchetfreak ধন্যবাদ, এই থামানো সমস্যার মতো জিনিসটি কখনও জানা যায় না যা আমার ইচ্ছা করে যে আমি রসায়নের পরিবর্তে কমপ সায়িতে আমার ডিগ্রি পেয়েছি।
জেলকন

15
@ জেলকন 5, আপনি এখন রসায়ন এবং থামার সমস্যা সম্পর্কে জানেন ... :)
ডেভিড আরনো

7
@ ইউফোরিক আপনি যদি আপনার প্রোগ্রামটি কাঠামো না করেন তবে কোনও রিসোর্স ব্যবহৃত হওয়ার সীমানা খুব স্পষ্ট যেমন RAII এর সাথে বা রিসোর্স-উইথ রিসোর্সগুলির সাথে
rathethet freak

উত্তর:


23

এটি (স্বীকৃত) উদাহরণটি ধরুন:

void* resource1;
void* resource2;

while(true){

    int input = getInputFromUser();

    switch(input){
        case 1: resource1 = malloc(500); break;
        case 2: resource2 = resource1; break;
        case 3: useResource(resource1); useResource(resource2); break;
    }
}

কখন ফোন করা উচিত? ম্যালোক এবং অ্যাসাইন করার আগে resource1আমরা এটি করতে পারি না কারণ এটি অনুলিপি করা হতে পারে resource2, অ্যাসাইন করার আগে resource2আমরা পারি না কারণ আমরা হস্তক্ষেপ 1 ছাড়াই দুবার ব্যবহারকারীর কাছ থেকে 2 পেয়েছি।

নিশ্চিত হওয়ার একমাত্র উপায় হ'ল 1 এবং 2 এর ক্ষেত্রে তারা সমান নয় কি না তা দেখার জন্য 1 সংস্থান এবং রিসোর্স 2 পরীক্ষা করে এবং পুরানো মানটি যদি তা না হয় তবে তা মুক্ত করে। এটি মূলত রেফারেন্স গণনা যেখানে আপনি জানেন কেবলমাত্র 2 টি সম্ভাব্য রেফারেন্স রয়েছে।


আসলে এটিই একমাত্র উপায় নয়; অন্য উপায়টি হ'ল কেবল একটি অনুলিপি থাকার অনুমতি দেওয়া । এটি অবশ্যই তার নিজস্ব সমস্যা নিয়ে আসে।
জ্যাক এইডলি

27

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

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

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


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
ম্যাপেল_শ্যাফ্ট

13

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

অঞ্চলভিত্তিক মেমরি পরিচালনার ক্ষেত্রে একটি পূর্বপরিকল্পনা হ'ল এমএল কিটের মূল লেখকদের একটি নিবন্ধ যা এর সাফল্য এবং ব্যর্থতায় যায়। চূড়ান্ত উপসংহারটি হ'ল একটি হিপ প্রোফাইলারের সহায়তায় লেখার সময় কৌশলটি ব্যবহারিক।

(আপনি ব্যবহারিক ইঞ্জিনিয়ারিং প্রশ্নগুলির উত্তরের জন্য সাধারণত হাল্টিং সমস্যার দিকে কেন নজর দেবেন না এটির একটি ভাল চিত্র: বেশিরভাগ বাস্তববাদী প্রোগ্রামগুলির জন্য আমরা সাধারণ পরিস্থিতি সমাধান করতে চাই না বা প্রয়োজন নেই ))


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

নোট করুন যে আমরা যখন স্ট্যান্ডার্ড এমএল এবং হাস্কেলের মতো খাঁটি বা প্রায় খাঁটি কার্যকরী, পার্শ্ব-প্রতিক্রিয়াশীল ভাষার বিষয়ে কথা বলি তখন সমস্যাটি আরও সমাধানযোগ্য হয়
বিড়াল

10

প্রোগ্রামটির নিয়ন্ত্রণ প্রবাহের সমস্ত অনুমতি অনুমান করুন

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


ভাল যুক্তি. আমার ধারণা কোয়ান্টাম প্রসেসরগুলি একমাত্র আশা, যদি কিছু থাকে তবে
জেলকন

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

8

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

আপনার যদি খাঁটি ফাংশন বা সত্যিকারের ভাল মালিকানার শব্দার্থবিজ্ঞান থাকে তবে আপনি সেই স্থির বিশ্লেষণ আরও বাড়িয়ে দিতে পারেন, যদিও আপনার কোডটি যত বেশি শাখা গ্রহণ করে তা করা নিষিদ্ধভাবে আরও ব্যয়বহুল হয়ে যায়।


ঠিক আছে, সংকলক মনে করে এটি স্মৃতি মুক্ত করতে পারে; তবে এটি নাও হতে পারে। কোনও পয়েন্টার বা কোনও স্থানীয় ভেরিয়েবলের রেফারেন্স ফেরত দেওয়ার জন্য সাধারণ শুরুর ত্রুটির কথা ভাবুন। তুচ্ছ ঘটনাগুলি সংকলক দ্বারা ধরা হয়, সত্য; তুচ্ছ কম হয় না।
পিটার - মনিকা পুনরায়

প্রোগ্রামাররা ভাষাগুলিতে প্রোগ্রামাররা যে ভুলটি প্রোগ্রামারদের ম্যানুয়ালি মেমোরি বরাদ্দ @ পিটার পরিচালনা করতে হবে সেই ভুলটি সেই ভুল করে । সংকলক যখন মেমরি বরাদ্দ পরিচালনা করে, তখন এই ধরণের ভুল ঘটে না।
কার্ল বিলেফেল্ট

ভাল, আপনি "প্রায় সমস্ত সংকলক" বাক্যাংশ সহ একটি খুব সাধারণ বিবৃতি দিয়েছেন যার মধ্যে অবশ্যই সি সংকলক অন্তর্ভুক্ত থাকতে হবে।
পিটার - মনিকা পুনরায়

2
অস্থায়ী ভেরিয়েবলগুলি রেজিস্টারে কী বরাদ্দ করা যায় তা নির্ধারণ করতে সি সংকলকরা এটি ব্যবহার করে।
কার্ল বিলেফেল্ট

4

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

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

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

কিছু বিকল্প আছে (কিছু উদীয়মান)।

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

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


3
অবশ্যই, জিসির খরচ আছে তবে এর কার্যকারিতা সুবিধাও রয়েছে। উদাহরণস্বরূপ, .NET- এ, গাদা থেকে বরাদ্দকরণ প্রায় বিনামূল্যে, কারণ এটি "স্ট্যাক-বরাদ্দ" প্যাটার্ন ব্যবহার করে - কেবলমাত্র একটি পয়েন্টার বৃদ্ধি করে, এবং এটিই। আমি ম্যানুয়াল মেমোরি বরাদ্দ ব্যবহারের চেয়ে NET GC- র চারপাশে দ্রুত পুনরায় লিখে যাওয়া অ্যাপ্লিকেশনগুলি দেখেছি, এটি সত্যই পরিষ্কার নয়। একইভাবে, রেফারেন্স গণনা আসলে বেশ ব্যয়বহুল (কেবলমাত্র একটি জিসি থেকে বিভিন্ন স্থানে), এবং আপনি যদি এড়াতে পারেন তবে কিছু দিতে চাইছেন না। আপনি যদি রিয়েল-টাইম পারফরম্যান্স চান, স্থির বরাদ্দ প্রায়শই একমাত্র উপায়।
লুয়ান

2

যদি কোনও প্রোগ্রাম কোনও অজানা ইনপুটটির উপর নির্ভর করে না তবে হ্যাঁ, এটি সম্ভব হওয়া উচিত (সাবধানতার সাথে যে এটি একটি জটিল কাজ হতে পারে এবং দীর্ঘ সময় নিতে পারে; তবে প্রোগ্রামটির ক্ষেত্রেও এটি সত্য হবে)। সংকলনের সময় এই জাতীয় প্রোগ্রামগুলি সম্পূর্ণ সমাধানযোগ্য হবে; সি ++ পদে, তারা (প্রায়) সম্পূর্ণরূপে constexprএস এর সমন্বয়ে গঠিত হতে পারে । সহজ উদাহরণগুলি হ'ল পাই এর প্রথম 100 টি সংখ্যা গণনা করা বা একটি পরিচিত অভিধানকে বাছাই করা।


2

সাধারণভাবে, মেমরি মুক্ত করা হোলিং সমস্যার সমতুল্য - যদি আপনি কোনও প্রোগ্রাম কোনওভাবে (স্থিতিশীল) থামবে কিনা তা আপনি যদি স্ট্যাটিকভাবে বলতে না পারেন তবে এটি মেমরিটি (স্ট্যাটিকালি) মুক্ত করবে কিনা তা আপনি বলতে পারবেন না।

function foo(int a) {
    void *p = malloc(1);
    ... do something which may, or may not, halt ...
    free(p);
}

https://en.wikipedia.org/wiki/Halting_problem

বলেছিল, মরিচা খুব সুন্দর ... https://doc.rust-lang.org/book/ownership.html

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