Author Topic: আইফোন অ্যাপলিকেশনের ভাষাঃ অবজেকটিভ সি – মেমোরি ম্যানেজমেন্ট  (Read 1063 times)

Offline Md. Nurul Islam

  • Newbie
  • *
  • Posts: 26
  • Test
    • View Profile
প্রোগ্রামিং করতে এসে মেমোরি ম্যানেজমেন্ট শব্দটা শুনে অস্বস্তিতে পড়েনি এরকম কাউকে খুঁজে পাওয়া মনে হয় একটু কঠিন। অল্প কথায় মেমোরি ম্যানেজমেন্টের ধারনাটা এরকম, আমাদের কোন প্রোগ্রাম বা অ্যাপলিকেশন চলার জন্য যে মেমোরি লাগে সেটার পরিমাণ এবং আমাদের মেশিনের প্রসেসর এর কাজ করার ক্ষমতা সীমিত। কাজেই, আমাদের প্রোগ্রামগুলো এমনভাবে লিখতে হবে যেন সেটা আমাদের প্রোগ্রামের জন্য বরাদ্দ সীমিত জায়গা ও ন্যূনতম রিসোর্স ব্যবহার করে দ্রুতগতিতে চলতে পারে। এইজন্যই মেমোরি ম্যানেজমেন্ট যেকোন প্রোগ্রামিং ল্যাঙ্গুয়েজের ক্ষেত্রেই খুবই গুরুত্বপূর্ণ ব্যাপার।

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

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

আমরা যদি সেটা না করি তাহলে কি হবে ? তাহলে অপ্রয়োজনীয় অবজেক্ট আমাদের মেমোরি দখল করে বসে থাকবে , গারবেজ কালেক্টর অপ্রয়োজনীয় জিনিস পেয়েও সেটাকে ফ্রি করতে পারবে না, ফলে মেমোরি লিক হবে, প্রোগ্রাম ক্রাশ করবে।

অন্যান্য অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং ল্যাঙ্গুয়েজের সাথে অবজেক্টিভ সি এর কিছু পার্থক্য আছে। যেমন, জাভাতে আমাদের মেমোরি ম্যানেজমেন্ট নিয়ে বেশি কিছু ভাবতে হয়না কারন এতে গারবেজ কালেক্টর থাকে। এর কাজ হল, সেখানে যা অপ্রয়োজনীয় অবজেক্ট থাকে সেগুলোকে সংগ্রহ করে ফ্রি করে দেয়া। অবজেক্টিভ সি ২.০ তে গারবেজ কালেক্টর থাকলেও আইওএস প্ল্যাটফর্মে সেটা নেই ও ভবিষ্যতে আসারও সম্ভাবনা নেই। এখানে প্রোগ্রামারের দায়িত্ব একটু বেশি।

অবজেক্টিভ সিতে অবজেক্ট ওনারশিপ বলে একটা ব্যাপার আছে। ধরা যাক, আমাদের দুইটা ক্লাস আছে , ক্লাস A ও ক্লাস B। আমরা যদি ক্লাস A তে ক্লাস B এর কোন অবজেক্ট ব্যবহার করি তাহলে ক্লাস A হবে ক্লাস B অবজেক্ট এর মালিক বা ওনার। এটুকু বুঝতে পারলে মেমোরি ম্যানেজমেন্টের নিয়মগুলো এবার আমরা দেখতে পারব। নিয়ম মূলত ৪ টা।

    আমাদের কোন ক্লাস যদি অন্য কোন ক্লাসের অবজেক্ট অ্যালোকেট করে কিংবা কপি করে তাহলে আমাদের ক্লাস হবে সেই অন্য ক্লাসের ওনার। ওনারশিপের জন্য মূলত  alloc, allocWithZone, copy, copyWithZone, mutableCopy, mutableCopyWithZone ইত্যাদি মেথড ব্যাবহৃত হয়ে থাকে। এরকম ওনারশিপকে বলা হয় ডিরেক্ট ওনারশিপ।
    এরকম হতে পারে যে, আমাদের ক্লাস অন্য আরেকটা ক্লাসের ওনার নয়, কিন্তু সে চায় যে, অন্য ক্লাসটা যেন তার দরকারের সময় মেমোরিতে থাকে। সেটা কেমন ? খুব সোজা, যদি এমন হয় যে আমাদের ক্লাস অন্য একটা ক্লাসের কোন ক্লাস মেথড ব্যবহার করে তাহলে ঐ ক্লাসকে মেমোরিতে থাকতে হবে। এরকম ওনারশিপকে বলা হয় ইনডিরেক্ট ওনারশিপ।
    আমি (আমার ক্লাস) যদি অন্য একটা ক্লাসের অবজেক্ট এর ওনার হই, তবে দরকার শেষ হলে আমাকে নিজ দায়িত্বে তাকে রিলিজ করতে হবে। release, autorelease এই মেথডগুলো দিয়ে অবজেক্ট রিলিজ করা হয়।
    আমি (আমার ক্লাস) যদি অন্য একটা ক্লাসের অবজেক্ট এর ওনার না হই, তবে তাকে রিলিজ করার ক্ষমতা আমার নেই। রিলিজ করার চেষ্টা করলে সেটার ফল ভালো হবেনা যেহেতু সেটা আমার ক্ষমতার বাইরে।

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


কি কঠিন লাগছে ? :)

তাহলে ব্যাপারটা সহজ করে দিই। অবজেক্টিভ সি প্রোগ্রামারদের আজ থেকে কয়েক বছর আগেও এভাবে ম্যানুয়ালি মেমোরি ম্যানেজমেন্ট করতে হত উপরের মত। কিন্তু আইওএস ৫ থেকে অ্যাপল নতুন একটা সিস্টেম নিয়ে আসে। এটার নাম অটোম্যাটিক রেফারেন্স কাউন্টিং বা ARC । ARC কোন গারবেজ কালেক্টর নয়। এটা মেমোরি ম্যানেজমেন্ট এর নতুন একটা মডেল। এর কাজ হল, আমরা আমাদের কোডে যে অবজেক্টগুলো ব্যবহার করি তাদের রেফারেন্স কাউন্ট এর হিসাব রাখা। আমাদের প্রজেক্ট যদি ARC এনাবল করা হয় তাহলে আমাদেরকে retain, release, dealloc ইত্যাদি মেমোরি ম্যানেজমেন্ট মেথডগুলোকে কল করা লাগবেনা। ARC রেফারেন্স কাউন্ট হিসাব করে প্রোগ্রাম কম্পাইল টাইমে কোডের ভিতর যেখানে যেখানে দরকার সেখানে ঐ মেমোরি ম্যানেজমেন্ট এর মেথডগুলো যোগ করে দিয়ে কম্পাইল করবে। কাজেই এখন আমাদেরকে মেমোরি ম্যানেজমেন্ট নিয়ে এত মাথা না ঘামালেও কোন সমস্যা নেই।