রুবিতে মেমরি অ্যালোকেশন কীভাবে কাজ করে?
রুবি মেমরি চан্কগুলিতে পায়, যাকে পেজ বলা হয়, নতুন অবজেক্টগুলো এখানে সংরক্ষিত হয়।
তারপর...
যখন এই পেজগুলো ফুল হয়ে যায়, আরও মেমরির দরকার পড়ে।
রুবি অপারেটিং সিস্টেম থেকে malloc ফাংশন দিয়ে আরও মেমরি অনুরোধ করে।
এই malloc ফাংশনটি অপারেটিং সিস্টেমের অংশ, কিন্তু এর বিকল্প ইমপ্লিমেন্টেশনও আছে যা আপনি ব্যবহার করতে পারেন।
এই ইমপ্লিমেন্টেশনগুলোর একটি হলো গুগলের tcmalloc।
TCmalloc হলো গুগল পারফরম্যান্স টুলস স্যুটের অংশ।
আপনি এই টুলগুলো ব্যবহার করতে পারেন রুবি কীভাবে মেমরি অ্যালোকেট করে সেটি এক্সপ্লোর করতে।
এবং LD_PRELOAD এনভায়রনমেন্ট ভেরিয়েবল (লিনাক্সে)র সাহায্যে আমরা আপনার সিস্টেমের malloc ফাংশনকে tcmalloc-এ রিপ্লেস করতে পারি।
এভাবে:
LD_PRELOAD="/usr/lib/libtcmalloc.so" ruby -e "puts 123"
কিন্তু এটি শুধু লাইব্রেরি লোড করে, এখনো কোনো ডেটা কালেকশন সক্রিয় করে না।
আসুন দেখি এটি কীভাবে করা যায়।
প্রোফাইলার সক্রিয় করা
আপনি একটি অতিরিক্ত এনভায়রনমেন্ট ভেরিয়েবল (HEAPPROFILE) দিয়ে tcmalloc-এর প্রোফাইলার সক্রিয় করতে পারেন।
LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ruby -e "puts 123"
এটি নিচের আউটপুট দেবে:
Starting tracking the heap 123 Dumping heap profile to /tmp/profile.0001.heap (Exiting, 2 MB in use)
এখানে আপনি দেখতে পাচ্ছেন প্রোফাইলার সক্রিয় হয়েছে কনফার্মেশন।
তারপর আমরা দেখি:
- প্রোগ্রামের আউটপুট
- ফাইলনেম (
profile.0001.heap) - আমাদের প্রোগ্রাম দ্বারা ব্যবহৃত মেমরির পরিমাণ (
2 MB)
এই ফাইলটি পড়তে আপনাকে tcmalloc-এর সাথে আये আরেকটি টুল দরকার।
pprof --text `which ruby` /tmp/profile.0001.heap | head -10
এটি নিচের আউটপুট দেবে:
Total: 2.4 MB 1.1 44.7% 44.7% 1.1 44.7% 0x00005570fa4df074 0.7 27.8% 72.5% 0.7 27.8% 0x00005570fa4e0c09 0.4 15.3% 87.8% 0.4 15.3% 0x00005570fa4db460 0.1 5.9% 93.7% 0.1 5.9% 0x00005570fa4df19f 0.1 3.2% 96.9% 0.1 3.2% 0x00005570fa6349a0 0.0 1.4% 98.3% 0.0 1.4% 0x00005570fa589924 0.0 0.3% 98.6% 0.0 0.3% 0x00005570fa59c4f2 0.0 0.3% 98.8% 0.0 0.3% 0x00005570fa4db48a 0.0 0.2% 99.0% 0.0 0.2% 0x00005570fa4dbaa5 0.0 0.2% 99.1% 0.0 0.2% _dl_new_object
এই বাঙালি মেমরি অ্যাড্রেস! আপনাকে রুবির একটি ডিবাগ সিম্বলস যুক্ত ভার্সন দরকার ফাংশন নামগুলো দেখতে।
তখন আপনি এই আউটপুট পাবেন:
Using local file ruby. Using local file /tmp/profile.0001.heap. Total: 2.9 MB 1.0 36.2% 36.2% 1.0 36.2% objspace_xmalloc0 0.7 26.1% 62.4% 0.7 26.1% aligned_malloc 0.5 18.8% 81.1% 0.5 18.8% objspace_xcalloc 0.3 9.9% 91.0% 0.3 9.9% stack_chunk_alloc 0.1 3.7% 94.7% 0.1 3.7% objspace_xrealloc 0.1 2.7% 97.4% 0.1 2.7% Init_Method 0.0 1.3% 98.7% 0.0 1.7% onig_new_with_source 0.0 0.4% 99.2% 0.8 26.6% heap_page_allocate 0.0 0.2% 99.4% 0.0 0.2% add_bitset
এখানে আপনি দেখছেন MRI-এর কোন ফাংশন কতটুকু মেমরি অ্যালোকেট করেছে।
জানা দিলচস্প যে aligned_malloc হলো রুবি অবজেক্টের জন্য নতুন পেজ অ্যালোকেট করার ফাংশন, stack_chunk_alloc GC-র দ্বারা মার্কিং ফেজে ব্যবহার হয়, এবং objspace_xmalloc0 / objspace_xcalloc স্ট্রিং, অ্যারে এবং যেকোনো ডেটা যা RVALUE স্ট্রাক্টে ফিট না হয় তার জন্য স্পেস অ্যালোকেট করে।
এখন:
TCmalloc রুবি অবজেক্ট সম্পর্কে কিছুই না জানে, এটি শুধু malloc, calloc এবং realloc কল ট্র্যাক করে জানতে পারে কতটুকু মেমরি অনুরোধ করা হয়েছে।
যদি আপনি রুবি লেভেলে হিপ ডাম্প চান তবে আপনি ObjectSpace.dump_all ব্যবহার করতে পারেন। এটি আপনাকে একটি JSON ফাইল দেবে আপনার অ্যাপ্লিকেশনের সকল লাইভ অবজেক্ট এবং তাদের মেমরি সাইজসহ।
কিন্তু tcmalloc আপনাকে দেখাতে পারে সকল C ফাংশনের একটি ভিজ্যুয়ালাইজেশন যা মেমরি অনুরোধ করে শেষ পর্যন্ত।
pprof --web `which ruby` /tmp/profile.0001.heap
এটি Chrome বা Firefox খুলবে একটি SVG ফাইলসহ যা এরকম দেখায়:

TCmalloc শুধু এই সুন্দর প্রোফাইলিং ক্যাপাবিলিটি দেয় না, এটি ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনের পারফরম্যান্স ৪-৯% বাড়াতে পারেন! আপনি jemallocও ট্রাই করতে পারেন, যা আরেকটি malloc ইমপ্লিমেন্টেশন যাতে প্রোফাইলারও আছে।
সারসংক্ষেপ
আপনি শিখতে পেরেছেন কীভাবে gperftools (Google Performance Tools) ব্যবহার করে রুবি ইন্টারপ্রেটারের মেমরি ব্যবহার ভিজ্যুয়ালাইজ এবং অ্যানালাইজ করবেন।
পড়ার জন্য ধন্যবাদ! 🙂