জাভাতে মেমোরি ম্যানেজমেন্ট হল এমন একটা প্রসেস যার মাধ্যমে কোন অবজেক্ট মেমোরিতে একটি জায়গা নেয় এবং কাজ শেষে আবার স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায়। জাভা নিজে এই প্রসেসটা অটোমেটিক ভাবে করে থাকে। জাভার এই স্বয়ংক্রিয় মেমোরি ম্যানেজমেন্ট সিস্টেম কে বলা হয় গারবেজ কালেক্টর 'garbage collector'। অন্য অনেক ল্যাংগুয়েজে ম্যানুয়ালি অবজেক্ট বানাতে হয় এবং কাজ শেষে ধংস বা destroy করে দিতে হয়। কিন্তু একজন জাভা ডেভেলপারের জাভা মেমোরি ম্যানেজমেন্ট সম্পর্কে জানা উচিত।
জাভাতে মেমোরি প্রধানত দুই প্রকারঃ
১. স্ট্যাক (Stack)
২. হিপ (Heap)
স্ট্যাক (Stack)
স্ট্যাক মেমোরিতে রাখা হয় হিপ মেমোরিতে থাকা কোন অবজেক্টের রেফারেন্স এবং জাভার ভ্যালু টাইপ যেটা জাভাতে primitive হিসেবে পরিচিত যেমনঃ int, boolean ইত্যাদি। স্ট্যাক হল "Last In First Out"। যখন কোন নতুন মেথড কল হবে স্ট্যাক এর ভেতরে নতুন একটা ব্লক তৈরি হবে যার ভেতরে ওই মেথডের কিছু ভ্যালু থাকবে যেমন primitive variables আর অবজেক্টের রেফারেন্স। যখন মেথডের কাজ শেষ হয়ে যাবে তখন স্ট্যাক ওই ভ্যালু টা মুছে যাবে।
হিপ (Heap)
স্ট্যাক মেমোরিতে যার রেফারেন্স থাকবে সেই অবজেক্টের সব কিছু থাকবে হিপ মেমোরিতে।
StringBuilder builder = new StringBuilder();
এই new কি ওয়ার্ড ব্যবহারের মাধ্যমে আমরা হিপে অবজেক্টের জন্য যা জায়গা দরকার হয় সেই পরিমান মেমোরি পাই। আমরা StringBuilder অবজেক্ট মেমোরিতে তৈরি করেছি এবগ এইটার রেফারেন্স নাম builder যেটা স্ট্যাক মেমোরিতে সেভ আছে। প্রতিটা JVM প্রসেসে একটাই হিপ মেমোরি থাকে। হিপ নিজেই কিছু অংশে বিভক্ত থাকে garbage collection প্রসেস চালানোর জন্য। এটার সাইজ নির্দিষ্ট করা থাকে না এটা নির্ভর করে মেশিনের উপর।
রেফারেন্স টাইপ (Reference Type)
হিপ মেমোরিতে যেই অবজেক্ট থাকে সেগুলোর রেফারেন্স থাকে স্ট্যাক মেমোরিতে। এই রেফারেন্স বিভিন্ন কাজের ধরন অনুসারে বিভিন্ন ধরনের হয়ে থাকে। রেফারেন্স ৪ ধরনের হয়। সেগুলো হলঃ
১. স্ট্রং রেফারেন্স (Strong Reference)
সবচেয়ে প্রচলিত রেফারেন্স টাইপ হল এইটা। উপরের উদাহরনে StringBuilder আছে এইটা হল স্ট্রং রেফারেন্স। এই অবজেক্ট গারবেজ হিসেবে যায় না যতক্ষন পর্যন্ত এইটার উপর স্ট্রং রেফারেন্স পয়েন্ট করে থাকে।
২. উইক রেফারেন্স (Weak Reference)
উইক রেফারেন্স যখন হিপে থাকা অবজেক্টের উপর পয়েন্ট করা থাকে তাহলে নেক্সট গারবেজ কালেকশান প্রসেসে সেটা ডিলিট হয়ে যায়।
WeakReference<StringBuilder> reference = new WeakReference<>(new StringBuilder());
৩. সফট রেফারেন্স (Soft Reference)
এই ধরনের রেফারেন্স ব্যবহার করা মেমোরি সেনসিটিভ ক্ষেত্রে, যখন অ্যাপ্লিকেশান মেমোরি স্পেস কমে যায় তখন এর গারবেজ কালেক্ট হয়। এইটা কিছু উইক রেফারেন্সের মতই। কিন্তু পার্থক্য হছে এই রেফারেন্সের অবজেক্ট গুলো তখনই গারবেজ হিসেবে কালেক্ট হয় যখন ক্রিটিকালি আমাদের মেমোরি ফাকা করার দরকার পড়ে। যখন জাভা প্রোগ্রাম OutOfMemoryError দেয় তার আগে সকল সফট রেফারেন্স অবজেক্ট ক্লিয়ার হয়ে যায়।
SoftReference<StringBuilder> reference = new SoftReference<>(new StringBuilder());
৪. ফ্যান্টম রেফারেন্স (Phantom Reference)
ফ্যান্টম রেফারেন্স কালেক্টরে যোগ হয় এমনভাবে যেন এইটা পরবর্তীতে আবার চাইলে খুজে পাওয়া যায়। জাভা ফাইনালাইজেশন মেকানিজম এর পরিবর্তে ফ্যান্টম রেফারেন্স pre-mortem cleanup করে একটু ফ্লেক্সিবল ভাবে। উইক আর সফট রেফারেন্সের মত এই ক্ষেত্রে অটোমেটিক গারবেজ কালেক্ট করে না।
PhantomReference<StringBuilder> reference = new PhantomReference<>(new StringBuilder());
গারবেজ কালেকশান যেভাবে কাজ করে
রেফারেন্সের ধরনের উপর ভিত্তি করে কোন অবজেক্ট গারবেজ কালেক্টের জন্য রেডি হয়ে থাকে। যখন কোন অবজেক্ট গারবেজ কালেক্টের জন্য এলিজিবল হয়ে যায় তখন স্ট্যাকে যে কোন অবজেক্টের রেফারেন্স থাকলে সেটা রিমুভ হয়ে যায়। আর এক বার স্ট্যাক থেকে রেফারেন্স হারিয়ে গেলে সেটা চিরতবে হারয়ে যায়। হিপের ভেতরে গারবেজ কালেক্টর যখন দেখে সেই রেফারেন্স বিহীন অবজেক্টকে মেমোরি থেকে মুছে ফেলে।
কিছু গুরুত্বপূর্ণ ব্যাপার গারবেজ কালেকশানের ক্ষেত্রেঃ
- জাভা অটোমেটিকালি গারবেজ কালেকশান প্রসেস ট্রিগার করে এবং এটা কখন শুরু হবে এটা জাভা পুরোপুরি নিজেই নিয়ন্ত্রন করে।
- এটা অনেক ব্যায়বহুল প্রসেস কারন যখন গারবেজ কালেকশান চলে তখন অন্যান্য থ্রেড বন্ধ হয়ে যায়।
- এটা একটু জটিল প্রক্রিয়া শুধু গারবেজ কালেক্ট আর মেমোরি ফ্রি করে দেওয়া এর ভিতরেই সীমাবদ্ধ না।
যদি ও জাভা নিজেই ঠিক করে নেয় কখন গারবেজ কালেক্টর রান করবে কিন্তু তারপর ও System.gc() আমরা ম্যানুয়ালি কল করতে পারি। কিন্তু ম্যানুয়ালি System.gc() কল করা সাজেস্ট করা হয় না।
জাভা গারবেজ কালেক্টরের প্রকারভেদঃ
1. Serial GC
সিঙ্গেল থ্রেড কালেক্টর। ছোট অ্যাপ্লিকেশন ছোট ডেটার ক্ষেত্রে ব্যবহৃত হয়।
2. Parallel GC
গারবেজ কালেক্টর এই ক্ষেত্রে এক সাথে অনেকগুলো থ্রেডের মাধ্যমে রান হয়।
3. Mostly concurrent GC
আগেই আমরা একবার বলেছি, গারবেজ কালেক্টিং হল ব্যায়বহুল প্রক্রিয়া এবং এই সময় সকল থ্রেড বন্ধ থাকে। Mostly concurrent GC গারবেজ কালেকশান করে অ্যাপ্লিকেশনের সাথে কনকারেন্টলি অর্থাৎ একই সাথে বা পাশাপাশি। এটাকে আমরা বলছি Mostly concurrent কারন এটা পুরোপুরি ১০০% কনকারেন্ট না। একটা নির্দিষ্ট সময় পর্যন্ত থ্রেড বন্ধ করে আবার চালু করা হয়। এবং থ্রেড বন্ধ থাকা সময় টা যথাসম্ভব ছোট রাখা হয় যেন গারবেজ কালেক্টর ভাল পারফরমেন্স দেয়।