আমরা , আজকে মেমোরী'র দুইটি অংশ Stack & Heap নিয়ে কথা বলবো ।। তার আগে , আমরা চলো আগে একটা ছবি দেখে আসি ------------------------
Stack & Heap নামে মেমোরী'র দুইটি অংশই আমাদের কম্পিউটারের র্যামে সংরক্ষিত ।। এখন একটা জিনিস খুবই গুরুত্বপূর্ণ সেটা হলো -- static memory allocation এর জন্য
Stack ইউজ করা হয় ।। আর , dynamic memory allocation এর জন্য Heap ইউজ করা হয় ।। আমরা , যতো রকমের ফাংশন লিখি , বা ভ্যারিয়েবল ডিক্লেয়ার করি ( int x,double y,etc..) , সব কিছু এই স্ট্যাক মেমোরিতে স্টোর হয় এবং সকল ধরনের এক্সিকিউশন এই মেমোরিতেই হয় ।। আমরা একটা কোড লিখার পর , যখন সেটা কম্পাইল করা হয় , তখনই সবকিছুর আধার হিসেবে কাজ করে এই স্ট্যাক মেমোরী ।।
কিন্তু , যখন প্রোগ্রাম'টি রান করানো হয় --- তখন যদি , কখনো dynamic memory allocation এর প্রয়োজন পরে , তখন প্রোগ্রামটি তার চলাকালীন সময়ে হিপ মেমোরি'র জায়গা দখল করে ।।
তোমার যদি কোড লিখার সময়ই , জানা থাকে তোমার প্রোগ্রাম কতটুকূ জায়গা খাবে ও তোমার ডেটা'র জায়গা বেশি বড়ো না হয়ে থাকে ??? তাহলে তুমি স্ট্যাক ইউজ করতে পারবা ।।
কিন্তু , তুমি যদি না জেনে থাকো তোমার প্রোগ্রাম কতটুকু জায়গা খাবে ?? অর্থাৎ প্রোগ্রামটি চলাকালীন সময়ে , তার কারযপরিধি বা ডেটা'র পরিমাণ বাড়াতে চায় , তখন তোমায় হিপ মেমোরী'র বযবস্থা রাখতে হবে ।। এটাকে , ভার্চুয়াল মেমোরি বলা হয় , যেটা প্রোগ্রাম চলাকালীন তার রানটাইমে মেমোরি এলোকেট করতে ইউজ করে ।। তবে একটাই সমস্যার কথা , সেটা হলো - হিপ মেমোরি অ্যাকসেস করা , স্ট্যাক মেমোরী'র এর থেকে কিছুটা স্লো ।।
যাই হোক , এখন আসি -- আরেকটা গুরুত্বপূর্ণ বিষয়ে সেটা হলো , রেফারেন্স টাইপ ও ভ্যালু টাইপ ।। খুব ভালো করে তোমায় বুঝতে হবে বিষয়টা ।। তুমি যে , নরমালি একটা ইন্টিজার ভ্যারিয়েবল ডিক্লেয়ার করো , সেটা সাধারনত সেই ডেটাটাইপের ভ্যালু স্টোর করে , এখান থেকেই এর নাম হয়েছে ভ্যালু টাইপ ।। আচ্ছা , এটা কিভাবে কাজ করে ???
int x লিখা মানে , স্ট্যাক এ x নামে একটা চার বাইটের মেমোরি এলোকেট হয় । ব্যাস এইটুকুই ।। এটা হলো ভ্যালু টাইপ ।।
কিন্তু , তুমি যখন একটা অবজেক্ট ক্রিয়েট করবা , তখন কি হয় ???? ধরো , তুমি
Form1 নামে একটা ক্লাসের অবজেক্ট ক্রিয়েট করলা ।।
Form1 frm = new Form1();
তাহলে ,new Form1() দ্বারা আমরা একটা অবজেক্ট ক্রিয়েট করলাম , হিপ মেমোরিতে ।।
আর , frm নামের একটা ভ্যারিয়েবল ক্রিয়েট করলাম , এইটা হিপ মেমোরিতে থাকা Form1
ক্লাসের যে অবজেক্ট খুললাম , তার মেমোরি'র অ্যাড্রেস স্টোর করে রাখে ।। এটা মাথায় ঠিকভাবে রাখা উচিত , এই frm নামের ভ্যারিয়েবল Form1 ক্লাসের যে অবজেক্ট আছে তার কোনো ডেটা কিন্তু স্টোর করে না , এটা শুধু সেই অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে রাখে ।। frm আসলে একটা পয়েন্টার ভ্যারিয়েবল , এটা মেমোরি'র অ্যাড্রেস পয়েন্ট করে ।।
তো যাই হোক , আমরা নরমাল যে ডেটাটাইপ গুলো দিয়ে ভ্যারিয়েবল ডিক্লেয়ার করি , সেগুলো
সবগুলোই তাদের ডেটাটাইপ অনুসারে ভ্যালু স্টোর করে , তাই এগুলোকে ভ্যালু টাইপ ভ্যারিয়েবল
বলা হয় ।। আর , আমরা অব্জেক্ট ক্রিয়েট করবার সময় , যে -- ভ্যারিয়েবল ক্রিয়েট করি , সেই সবগুলিই শুধু সেই অব্জেক্ট এর রেফারেন্স ( অ্যাড্রেস ) স্টোর করে , তাই এগুলোকে রেফারেন্স
ভযারিয়েবল বলা হয় ।।
আশা করি , এই বিষয়টা একদম ক্লিয়ার । তারপরো যদি , খটকা লাগে , তাহলে পুরোটা আরো একবার পড়ে নাও ।।
আচ্ছা এবার আমরা , স্ট্রাকট ও ক্লাসের ডিফারেন্স নিয়ে কথা বলবো ।।
১) স্ট্রাকচার ক্রিয়েট করলে , সেটা স্ট্যাক মেমোরিতে স্টোর হয় ।। আর ক্লাস এর ক্ষেত্রে অব্জেক্ট হিপ মেমোরিতে স্টোর হয় ।।
২) স্ট্রাকচার ভ্যালু টাইপ , আর ক্লাসে হলো রেফারেন্স টাইপ ।।
৩) একটা শূন্য স্ট্রাকচার মেমোরিতে কোনো জায়গা দখল করে না ।। বাট , একটা শুণ্য ক্লাস মে্মোরিতে এক বাইট জায়গা দখল করে ।।
৪) স্ট্রাকচারের ক্ষেত্রে ,ইনহেরিটেন্স ঘটে না - এর মানে স্ট্রাকচার কে কখনো বেইস স্ট্রাকচার হিসেবে - আর কোনো স্ট্রাকচার ক্রিয়েট করা যাবে না ।। কিন্তু , ক্লাসের ক্ষেত্রে ইনহেরিটেন্স সাপোর্ট করে ।।
৫) তুমি যখন , একটা স্ট্রাকচার থেকে আরেকটা স্ট্রাকচার কপি করবা , তখন পুরো স্ট্রাকচারের একটা কপিই ক্রিয়েট হয় , মেমোরিতে ।। কিন্তু , তুমি যখন একটা ক্লাস এর কপি করো , তখন কিন্তু পুরো ক্লাস আর কপি হয় না , শুধু নতুন একটা রেফারেন্স ভ্যারিয়েবলই ক্রিয়েট হয় , যেটা ঐ ক্লাস এর অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে ।। চলো , একটা উদাহরন দেখে আসি ---
using System;
public class student
{
public string name;
public int id;
public void print()
{
Console.WriteLine("Student's Name {0} , ID No . = {1} ", this.name, this.id);
}
}
public class Program
{
public static void Main()
{
student s = new student();
s.name = "Joy";
s.id = 101;
student a = s;
a.id=100;
a.name = "JOYA";
s.print();
Console.ReadKey();
}
}
আমরা , এখানে student s রেফারেন্স ভ্যারিয়েবল ক্রিয়েট এর পরেও , আরো একটা রেফারেন্স ভ্যারিয়েবল ক্রিয়েট করে প্রথমটা থেকে কপি করে নিলাম student a = s;student a = s ।। তাহলে , আসলে কি হলো ??? তুমি , সেই একই student ক্লাসের অ্যাড্রেস ,এবার a নামক রেফারেন্স ভ্যারিয়েবলে অ্যাসাইন করে নিলে ।। এর মানে , a দিয়েও তুমি ওই student ক্লাসের অব্জেক্ট এর
ডেটা চেইঞ্জ করতে পারবা , আর S দিয়ে তো পারবেই ।।
৬) ক্লাসের ডিস্ট্রাক্টর থাকতে পারে , বাট স্ট্রাকচার এর কোনো ডিস্ট্রাক্টর নেই ।।
৭) ক্লাসের পযারামিটারলেস কনস্ট্রাকটর থাকতে পারে , বাট স্ট্রাকচার এর থাকে না ।।
চলো , একটু উদাহরণ দেখে আসি --------------------------------------
using System;
public class student
{
public string name;
public int id;
public student()
{
}
}
public class Program
{
public static void Main()
{
Console.ReadKey();
}
}
এই কোড'টাকে রান করাও , কোনো আওউটপুট কন্সল স্ক্রিনে দেখতে পাবে না , কারণ আমি কিছু লিখি নি ।। কিন্তু , বিল্ড করার সময় কোনো এরর পাবা না ।।আমরা , এখানে -- প্যারামিটারলেস কনস্ট্রাকটর ক্রিয়েট করেছি ।। কিন্তু , উপরের কোড'টাই জাস্ট class এর যায়গায় শুধু struct দিয়ে লিখো ।। দেখবা , রান করাতেই পারবা না , এরর খাবা ।।
আচ্ছা , আমরা তো এটা জানি যে - স্ট্রাকচার থেকে ডিরাইভড স্ট্রাকচার বের করা যায় না ।। এখন আমি যদি চাই যে - আমি ক্লাসকে এমন বযবস্থা করতে চাই , যেনো - সেই ক্লাস থেকেওন্য কেউ আর কোনো ক্লাস ইনহেরিট করতে না পারে ।। তাইলে কিভাবে করবো ?? বলো তো -----------------------
using System;
public sealed class student
{
public string name;
public int id;
public student()
{
}
}
public class Program
{
public static void Main()
{
Console.ReadKey();
}
}
তাহলে , তুমি যদি কোনো ক্লাসের আগে , sealed কিওয়ারড ইউজ করো , তাহলে - সেই ক্লাস থেকে অনয কোনো ক্লাস ডিরাইভড হবে না ।।
স্ট্রাকচারও প্রকৃতপক্ষে উপরের ক্লাসের মতোই অটোমেটিক sealed টাইপস ।। তাই , স্ট্রাকচার থেকে ইনহেরিটেড করা যায় না ।। আজ এইটুকুই ------------------------
s
Stack & Heap নামে মেমোরী'র দুইটি অংশই আমাদের কম্পিউটারের র্যামে সংরক্ষিত ।। এখন একটা জিনিস খুবই গুরুত্বপূর্ণ সেটা হলো -- static memory allocation এর জন্য
Stack ইউজ করা হয় ।। আর , dynamic memory allocation এর জন্য Heap ইউজ করা হয় ।। আমরা , যতো রকমের ফাংশন লিখি , বা ভ্যারিয়েবল ডিক্লেয়ার করি ( int x,double y,etc..) , সব কিছু এই স্ট্যাক মেমোরিতে স্টোর হয় এবং সকল ধরনের এক্সিকিউশন এই মেমোরিতেই হয় ।। আমরা একটা কোড লিখার পর , যখন সেটা কম্পাইল করা হয় , তখনই সবকিছুর আধার হিসেবে কাজ করে এই স্ট্যাক মেমোরী ।।
কিন্তু , যখন প্রোগ্রাম'টি রান করানো হয় --- তখন যদি , কখনো dynamic memory allocation এর প্রয়োজন পরে , তখন প্রোগ্রামটি তার চলাকালীন সময়ে হিপ মেমোরি'র জায়গা দখল করে ।।
তোমার যদি কোড লিখার সময়ই , জানা থাকে তোমার প্রোগ্রাম কতটুকূ জায়গা খাবে ও তোমার ডেটা'র জায়গা বেশি বড়ো না হয়ে থাকে ??? তাহলে তুমি স্ট্যাক ইউজ করতে পারবা ।।
কিন্তু , তুমি যদি না জেনে থাকো তোমার প্রোগ্রাম কতটুকু জায়গা খাবে ?? অর্থাৎ প্রোগ্রামটি চলাকালীন সময়ে , তার কারযপরিধি বা ডেটা'র পরিমাণ বাড়াতে চায় , তখন তোমায় হিপ মেমোরী'র বযবস্থা রাখতে হবে ।। এটাকে , ভার্চুয়াল মেমোরি বলা হয় , যেটা প্রোগ্রাম চলাকালীন তার রানটাইমে মেমোরি এলোকেট করতে ইউজ করে ।। তবে একটাই সমস্যার কথা , সেটা হলো - হিপ মেমোরি অ্যাকসেস করা , স্ট্যাক মেমোরী'র এর থেকে কিছুটা স্লো ।।
যাই হোক , এখন আসি -- আরেকটা গুরুত্বপূর্ণ বিষয়ে সেটা হলো , রেফারেন্স টাইপ ও ভ্যালু টাইপ ।। খুব ভালো করে তোমায় বুঝতে হবে বিষয়টা ।। তুমি যে , নরমালি একটা ইন্টিজার ভ্যারিয়েবল ডিক্লেয়ার করো , সেটা সাধারনত সেই ডেটাটাইপের ভ্যালু স্টোর করে , এখান থেকেই এর নাম হয়েছে ভ্যালু টাইপ ।। আচ্ছা , এটা কিভাবে কাজ করে ???
int x লিখা মানে , স্ট্যাক এ x নামে একটা চার বাইটের মেমোরি এলোকেট হয় । ব্যাস এইটুকুই ।। এটা হলো ভ্যালু টাইপ ।।
কিন্তু , তুমি যখন একটা অবজেক্ট ক্রিয়েট করবা , তখন কি হয় ???? ধরো , তুমি
Form1 নামে একটা ক্লাসের অবজেক্ট ক্রিয়েট করলা ।।
Form1 frm = new Form1();
তাহলে ,new Form1() দ্বারা আমরা একটা অবজেক্ট ক্রিয়েট করলাম , হিপ মেমোরিতে ।।
আর , frm নামের একটা ভ্যারিয়েবল ক্রিয়েট করলাম , এইটা হিপ মেমোরিতে থাকা Form1
ক্লাসের যে অবজেক্ট খুললাম , তার মেমোরি'র অ্যাড্রেস স্টোর করে রাখে ।। এটা মাথায় ঠিকভাবে রাখা উচিত , এই frm নামের ভ্যারিয়েবল Form1 ক্লাসের যে অবজেক্ট আছে তার কোনো ডেটা কিন্তু স্টোর করে না , এটা শুধু সেই অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে রাখে ।। frm আসলে একটা পয়েন্টার ভ্যারিয়েবল , এটা মেমোরি'র অ্যাড্রেস পয়েন্ট করে ।।
তো যাই হোক , আমরা নরমাল যে ডেটাটাইপ গুলো দিয়ে ভ্যারিয়েবল ডিক্লেয়ার করি , সেগুলো
সবগুলোই তাদের ডেটাটাইপ অনুসারে ভ্যালু স্টোর করে , তাই এগুলোকে ভ্যালু টাইপ ভ্যারিয়েবল
বলা হয় ।। আর , আমরা অব্জেক্ট ক্রিয়েট করবার সময় , যে -- ভ্যারিয়েবল ক্রিয়েট করি , সেই সবগুলিই শুধু সেই অব্জেক্ট এর রেফারেন্স ( অ্যাড্রেস ) স্টোর করে , তাই এগুলোকে রেফারেন্স
ভযারিয়েবল বলা হয় ।।
আশা করি , এই বিষয়টা একদম ক্লিয়ার । তারপরো যদি , খটকা লাগে , তাহলে পুরোটা আরো একবার পড়ে নাও ।।
আচ্ছা এবার আমরা , স্ট্রাকট ও ক্লাসের ডিফারেন্স নিয়ে কথা বলবো ।।
১) স্ট্রাকচার ক্রিয়েট করলে , সেটা স্ট্যাক মেমোরিতে স্টোর হয় ।। আর ক্লাস এর ক্ষেত্রে অব্জেক্ট হিপ মেমোরিতে স্টোর হয় ।।
২) স্ট্রাকচার ভ্যালু টাইপ , আর ক্লাসে হলো রেফারেন্স টাইপ ।।
৩) একটা শূন্য স্ট্রাকচার মেমোরিতে কোনো জায়গা দখল করে না ।। বাট , একটা শুণ্য ক্লাস মে্মোরিতে এক বাইট জায়গা দখল করে ।।
৪) স্ট্রাকচারের ক্ষেত্রে ,ইনহেরিটেন্স ঘটে না - এর মানে স্ট্রাকচার কে কখনো বেইস স্ট্রাকচার হিসেবে - আর কোনো স্ট্রাকচার ক্রিয়েট করা যাবে না ।। কিন্তু , ক্লাসের ক্ষেত্রে ইনহেরিটেন্স সাপোর্ট করে ।।
৫) তুমি যখন , একটা স্ট্রাকচার থেকে আরেকটা স্ট্রাকচার কপি করবা , তখন পুরো স্ট্রাকচারের একটা কপিই ক্রিয়েট হয় , মেমোরিতে ।। কিন্তু , তুমি যখন একটা ক্লাস এর কপি করো , তখন কিন্তু পুরো ক্লাস আর কপি হয় না , শুধু নতুন একটা রেফারেন্স ভ্যারিয়েবলই ক্রিয়েট হয় , যেটা ঐ ক্লাস এর অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে ।। চলো , একটা উদাহরন দেখে আসি ---
using System;
public class student
{
public string name;
public int id;
public void print()
{
Console.WriteLine("Student's Name {0} , ID No . = {1} ", this.name, this.id);
}
}
public class Program
{
public static void Main()
{
student s = new student();
s.name = "Joy";
s.id = 101;
student a = s;
a.id=100;
a.name = "JOYA";
s.print();
Console.ReadKey();
}
}
আমরা , এখানে student s রেফারেন্স ভ্যারিয়েবল ক্রিয়েট এর পরেও , আরো একটা রেফারেন্স ভ্যারিয়েবল ক্রিয়েট করে প্রথমটা থেকে কপি করে নিলাম student a = s;student a = s ।। তাহলে , আসলে কি হলো ??? তুমি , সেই একই student ক্লাসের অ্যাড্রেস ,এবার a নামক রেফারেন্স ভ্যারিয়েবলে অ্যাসাইন করে নিলে ।। এর মানে , a দিয়েও তুমি ওই student ক্লাসের অব্জেক্ট এর
ডেটা চেইঞ্জ করতে পারবা , আর S দিয়ে তো পারবেই ।।
৬) ক্লাসের ডিস্ট্রাক্টর থাকতে পারে , বাট স্ট্রাকচার এর কোনো ডিস্ট্রাক্টর নেই ।।
৭) ক্লাসের পযারামিটারলেস কনস্ট্রাকটর থাকতে পারে , বাট স্ট্রাকচার এর থাকে না ।।
চলো , একটু উদাহরণ দেখে আসি --------------------------------------
using System;
public class student
{
public string name;
public int id;
public student()
{
}
}
public class Program
{
public static void Main()
{
Console.ReadKey();
}
}
এই কোড'টাকে রান করাও , কোনো আওউটপুট কন্সল স্ক্রিনে দেখতে পাবে না , কারণ আমি কিছু লিখি নি ।। কিন্তু , বিল্ড করার সময় কোনো এরর পাবা না ।।আমরা , এখানে -- প্যারামিটারলেস কনস্ট্রাকটর ক্রিয়েট করেছি ।। কিন্তু , উপরের কোড'টাই জাস্ট class এর যায়গায় শুধু struct দিয়ে লিখো ।। দেখবা , রান করাতেই পারবা না , এরর খাবা ।।
আচ্ছা , আমরা তো এটা জানি যে - স্ট্রাকচার থেকে ডিরাইভড স্ট্রাকচার বের করা যায় না ।। এখন আমি যদি চাই যে - আমি ক্লাসকে এমন বযবস্থা করতে চাই , যেনো - সেই ক্লাস থেকেওন্য কেউ আর কোনো ক্লাস ইনহেরিট করতে না পারে ।। তাইলে কিভাবে করবো ?? বলো তো -----------------------
using System;
public sealed class student
{
public string name;
public int id;
public student()
{
}
}
public class Program
{
public static void Main()
{
Console.ReadKey();
}
}
তাহলে , তুমি যদি কোনো ক্লাসের আগে , sealed কিওয়ারড ইউজ করো , তাহলে - সেই ক্লাস থেকে অনয কোনো ক্লাস ডিরাইভড হবে না ।।
স্ট্রাকচারও প্রকৃতপক্ষে উপরের ক্লাসের মতোই অটোমেটিক sealed টাইপস ।। তাই , স্ট্রাকচার থেকে ইনহেরিটেড করা যায় না ।। আজ এইটুকুই ------------------------
s
No comments:
Post a Comment