মেমরি লিক মণি ব্যবহারকারীদের জন্য একটি যন্ত্রণাদায়ক. এগুলি ট্র্যাক করা কঠিন এবং ব্যয়বহুল অবকাঠামোগত খরচ হতে পারে৷
একটি সি এক্সটেনশনের মধ্যে মেমরি লিক আরও খারাপ। আপনি রুবিতে ফাঁস খুঁজে বের করার বিষয়ে অনেক সরঞ্জাম এবং নিবন্ধ দেখতে পাবেন। যাইহোক, C.
-এ আপনার অভ্যন্তরীণগুলিতে একই অ্যাক্সেস নেই
rb_funcall এর একটি নির্বোধ ব্যবহার মেমরি লিক হতে পারে:rb_protect ব্যবহার করা অনেক ভালো পরিবর্তে সুতরাং, আপনি যদি একজন সি এক্সটেনশনরাইটার হন, তাহলে অনুগ্রহ করে ডেভেলপারদের জন্য পড়ুন যারা আপনার মণি ব্যবহার করবে।
চলুন শুরু করা যাক!
rb_funcall এর সমস্যা এবং C
rb_funcall আপনার লাইব্রেরির রুবি এবং সি অংশগুলির মধ্যে ইন্টারঅ্যাক্ট করার প্রয়োজন হলে এটি একটি দুর্দান্ত সরঞ্জাম হতে পারে তবে শুধুমাত্র সামান্য সি লিখতে হবে৷
যাইহোক, যখন আপনি rb_funcall চালান , আপনি আর সি-তে নেই যেখানে সবকিছু সোজা। আপনি কাদা জলে ছেড়ে যেতে পারেন যদি ফাংশন বলা হয়:
- রানটাইম চলাকালীন সম্পূর্ণরূপে এর সংজ্ঞা পরিবর্তন করে
- একটি কল তোলে
1 নম্বরটি ধরা সবচেয়ে সহজ। আপনি সম্ভবত একটি সেগফল্টের সাথে শেষ হবেন, এবং যদি আপনার পরীক্ষা স্যুট যথেষ্ট সম্পূর্ণ হয়, তাহলে প্রকাশ করার আগে আপনার এটি ধরা উচিত।
যাইহোক, পরবর্তীটি মেমরি ফাঁসের কারণ হতে পারে এবং আপনার কোডবেসকে পড়া কঠিন করে তুলতে পারে। চলুন এখন সেটা দেখে নেওয়া যাক।
C মেমরি লিকস সৃষ্টিকারী রুবিতে বৃদ্ধি
রুবির উত্থাপন প্রক্রিয়া কোডের অংশগুলির মধ্যে একটি স্কোপ থেকে প্রথম পিতামাতার কাছে যায় যা একটি ত্রুটি ধরা দেয়। এটি longjmp ব্যবহার করে MRI তে প্রয়োগ করা হয় এবং setjmp .
আপনি যদি এটি কীভাবে তৈরি করা হয় তাতে আগ্রহী হন, রুবি হ্যাকিং গাইডের মূল্যায়নকারী অধ্যায়টি পড়ুন। সংক্ষেপে, আপনি যখন একটি begin..ensure ব্যবহার করেন ব্লক, আপনি setjmp() , এবং আপনি যখন এই ব্লকের মধ্যে বাড়াবেন, আপনি longjmp() সংরক্ষিত অবস্থানে।
তাই যদি একটি ফাংশন rb_funcall দিয়ে উত্থাপিত হয় , C কোড যা কখনো কার্যকর না হওয়ার পরে কল করা হয়।
নীচের উদাহরণটি একটি সম্ভাব্য ফাঁস চিত্রিত করে। যদি json_parse উত্থাপন, এটি লিক হবে.
অবশ্যই, উপরের উদাহরণটি একটু মূর্খ — আপনি freeing এবং Ruby প্রক্রিয়াকরণ অংশগুলিকে উল্টাতে পারেন। যাইহোক, এটি সর্বদা সম্ভব হয় না, এবং দীর্ঘতর ফাংশন সংস্থাগুলি আরও জড়িত হতে পারে।
begin..ensure ব্যবহার করা রুবিতে
আপনি যদি রুবি ব্যবহার করেন, তাহলে আপনি begin..ensure ব্যবহার করে উপরের উদাহরণটি লিখতে পারেন :
এই API rb_rescue সহ C-তেও উপলব্ধ এবং rb_ensure :
যাইহোক, এটি কিছুটা কষ্টকর, এবং আপনি যদি একটি rescue যোগ করতে চান পার্টিতে ব্লক করুন, এটি কম পঠনযোগ্য হয়। আমি পিটার ঝুর 'এ রুবিস্ট'স ওয়াক অ্যালং দ্য সি-সাইড পড়ার পরামর্শ দিই (পার্ট 8):আপনি যদি begin..rescue..ensure..end ব্যবহার করতে চান তবে ব্যতিক্রম এবং ত্রুটি হ্যান্ডলিং' C.
rb_protect ব্যবহার করা C
এর জন্য আরেকটি বিকল্প আছে। প্রথমে, আসুন দেখি এটি রুবিতে কেমন দেখতে পারে:
এটি রুবিতে অদ্ভুত দেখায়, কিন্তু এটি একটি ওয়ার্কফ্লো সি-এর জন্য খুব উপযুক্ত। এমআরআই এর জন্য একটি API রয়েছে, rb_protect , এবং C ফাংশনটি এইরকম দেখাচ্ছে:
উপরের পদ্ধতিটি ফ্রিডেভারিথিং করার পরে একটি রুবি ত্রুটি পুনরায় উত্থাপন করবে।
মনে রাখবেন যে আমরা anempty rescue ব্যবহার করে ত্রুটি উপেক্ষা করতেও বেছে নিতে পারি রুবিতে ব্লক:
সতর্কতা: আপনি ত্রুটি না বাড়ালে, rb_set_errinfo(Qnil) পদক্ষেপটি গুরুত্বপূর্ণ তাই আপনি এমন একটি ত্রুটি সম্পর্কে তথ্য উপলব্ধ রাখবেন না যা ব্যবহারকারীদের জানা উচিত নয়৷
অথবা, আপনি শর্তসাপেক্ষে একটি ত্রুটি উত্থাপন করতে বেছে নিতে পারেন, যেমন rescue My::Error :
আপনি আসলে rb_errinfo() বিবেচনা করতে পারেন $! এর মতই গ্লোবালভেরিয়েবল।
এটি সবই দুর্দান্ত, কিন্তু যখন এটি একটি rb_funcall এ ফুটে ওঠে শুধুমাত্র, আমরা সেই APIকে সরলীকরণ করতে পারি।
rb_protect ব্যবহার করার পিছনে সামগ্রিক ধারণা এপিআই যখন একটি ফাংশন আছে বাড়ানোর জন্য পঠনযোগ্যতা উন্নত করা হয়. ফাংশন বাড়াতে পারে কি না তা যাচাই করার দরকার নেই, আপনি ধরে নিচ্ছেন, এবং এর সাথে কাজ করার জন্য স্টেট ব্যবহার করুন।
rb_protect_funcall প্রস্তাব
চলুন বিচ্ছিন্ন করা যাক rb_funcall , কারণ এটি একমাত্র বিপজ্জনক ব্যবহার করার পদ্ধতি। এখানে একটি API যা এটি করবে:
এই API rb_funcall এর মতই , একটি state সহ rb_protect থেকে . তাই ব্যবহারটি বেশ সহজবোধ্য:
এই API এখনও Ruby এ উপলব্ধ নয়, এবং কখনও নাও হতে পারে৷ আপনি এটি আরজিও (এমআইটি লাইসেন্স) থেকে নিতে পারেন।
একটি বাস্তব-বিশ্বের উদাহরণ
আপনি যদি একটি বাস্তব-বিশ্বের উদাহরণ দেখতে চান, আমি আপনাকে RGeocodebase পড়তে উত্সাহিত করছি কারণ আমরা সম্প্রতি সম্পূর্ণ rb_protect তে স্যুইচ করেছি। . এমনকি আমাদের কিছু ফাংশন আছে, যেমন rgeo_convert_to_geos_geometry , যে সহজ ব্যবহারের জন্য এই রাষ্ট্র প্রচার. এই ফাংশনটি খনন শুরু করার জন্য একটি ভাল জায়গা৷
আমরা আরও যে পছন্দগুলি করেছি সেগুলি নিয়ে আলোচনা করতে RGeo-তে একটি সমস্যা খুলতে দ্বিধা বোধ করুন৷
৷র্যাপিং আপ
এই পোস্টে, আমরা rb_funcall ব্যবহার করার বিরুদ্ধে সতর্ক করেছি সি এর সাথে এটি মেমরি লিক হতে পারে। আমরা begin..ensure ব্যবহার করে অন্বেষণ করেছি অথবা rb_protect পরিবর্তে।
শুভ কোডিং!
পি.এস. আপনি যদি রুবি ম্যাজিক পোস্টগুলি প্রেস থেকে বের হওয়ার সাথে সাথে পড়তে চান তবে আমাদের রুবি ম্যাজিক নিউজলেটারে সাবস্ক্রাইব করুন এবং একটি পোস্ট মিস করবেন না!
Ulysse Buonomo
আমাদের অতিথি লেখক ইউলিস একজন প্রাক্তন ইন্ডাস্ট্রি রুবি ডেভেলপার যিনি তার বেশিরভাগ সময় সারা বিশ্বে ভ্রমণের জন্য উৎসর্গ করেন। তার অবসর সময় আরজিও এবং রুবিকে উত্সর্গ করা হয় এবং তিনি রুবির অভ্যন্তরীণ সাথে মিশতে পছন্দ করেন।
Ulysse Buonomo
এর সমস্ত নিবন্ধ