মেমরি লিক খুঁজে বের করার সম্পর্কে কিছু আর্টিকেল আছে।
কিন্তু একটা তৈরির সম্পর্কে কেমন?
আমি মনে করি এটি একটি আকর্ষণীয় এক্সারসাইজ হবে যাতে আপনি জানেন রুবিতে একটি মেমরি লিক কীভাবে দেখে।
আসুন কিছু উদাহরণ দেখি।
একটি সিম্পল লিক
আমরা একটি মেমরি লিক তৈরি করতে পারি শুধু নতুন অবজেক্টগুলো একটি অ্যারেতে যোগ করে।
এভাবে:
a = []
b = {}
loop { sleep(1)
10_000.times { a << "abc" }
puts GC.stat(b)[:heap_live_slots]
}
এটি প্রতি সেকেন্ডে ১০ হাজার স্ট্রিং তৈরি করে এবং একটি অবজেক্ট কাউন্ট প্রিন্ট করে:
285051 295052 305053 315054 325055 335056 345057 355058
কাউন্ট বড়তে থাকে কারণ GC এই স্ট্রিংগুলো কালেক্ট করতে পারে না, এগুলো কন্টেইনিং অ্যারে (a) দ্বারা রেফারেন্স করা হচ্ছে।
যদি a স্কোপ থেকে বাইরে চলে যায় তবে GC এই সব "abc" স্ট্রিংগুলো কালেক্ট করতে পারবে। আপনি উপরের উদাহরণে a-কে নিল সেট করে, তারপর GC.start রান করে টেস্ট করতে পারেন।
আপনি এখানে একটি লাইভ উদাহরণ পেতে পারেন, শুধু run ক্লিক করুন ফলাফল দেখতে।
C এক্সটেনশন লিক
যখন আপনি রুবি থেকে একটি অবজেক্ট তৈরি করেন, GC ট্র্যাক করে কতটুকু মেমরি ব্যবহার হচ্ছে, কিন্তু C এক্সটেনশন ব্যবহার করলে রুবির ওপর কোনো কন্ট্রোল নেই।
যদি আপনি এমন একটি C এক্সটেনশন তৈরি করেন:
#include#include "extconf.h" void *ptr; void Init_extension() { allocate_memory(); } void allocate_memory() { for(int i = 0; i < 10000; i++) { ptr = malloc(1000); } }
allocate_memory() ফাংশনটি মেমরি লিক করবে কারণ এটি malloc ব্যবহার করছে এবং সেই মেমরি রিলিজ করার জন্য free কল করছে না।
আপনি এখানে দেখতে পারেন:
`ps -o rss -p #{$$}`.lines.last # "49036"
require './extension'
`ps -o rss -p #{$$}`.lines.last # "89512"
এই ধরনের লিক কোনো হিপ ডাম্পে বা GC.stat-এ দেখাবে না, কিন্তু আপনি মেমরি ব্যবহার বর্ধমান দেখবেন।
সারসংক্ষেপ
এখন আপনি জানেন একটি মেমরি লিক কীভাবে দেখে, আশা করি এটি আপনাকে দ্রুত খুঁজে বের করতে সাহায্য করবে যদি কখনো এই সমস্যাটি হয়। বetails Ruby 2.4.1-এ একটি পরিচিত মেমরি লিক আছে, তাই আপনি আপগ্রেড করতে চাইতে পারেন যদি আপনি এই নির্দিষ্ট ভার্সন ব্যবহার করেন।
আপনার কি কোনো প্রশ্ন, ফিডব্যাক বা আকর্ষণীয় মেমরি লিক ডিবাগিং গল্প আছে? নিচে কমেন্ট করুন 🙂
পড়ার জন্য ধন্যবাদ!