এই বিভ্রান্তিটি আমি https://www.spicelogic.com/Blog/net-event-handler-memory-leak-16 এ ব্যাখ্যা করেছি । আমি এখানে সংক্ষিপ্ত করার চেষ্টা করব যাতে আপনি একটি পরিষ্কার ধারণা পেতে পারেন।
রেফারেন্স অর্থ, "প্রয়োজন":
প্রথমত, আপনার বুঝতে হবে যে, যদি বস্তু এ এর সাথে বস্তু বিয়ের একটি রেফারেন্স থাকে, তবে এর অর্থ হবে, অবজেক্ট এ কাজ করতে বস্তুর বি দরকার, তাই না? সুতরাং, আবর্জনা সংগ্রহকারী অবজেক্ট বিটি সংগ্রহ করবে না যতক্ষণ না বস্তু এ স্মৃতিতে বেঁচে থাকবে।
আমি মনে করি এই অংশটি কোনও বিকাশকারীর কাছে সুস্পষ্ট হওয়া উচিত।
+ = মানে, বাম বস্তুতে ডান দিকের বস্তুর রেফারেন্স ইনজেকশন:
তবে, বিভ্রান্তিটি সি # + = অপারেটর থেকে আসে। এই অপারেটরটি বিকাশকারীকে পরিষ্কারভাবে জানায় না যে, এই অপারেটরের ডান হাতটি আসলে বাম-হাতের বস্তুর একটি রেফারেন্স ইনজেক্ট করছে।
এবং এটি করার মাধ্যমে, বস্তু এ মনে করে, এটিতে অবজেক্ট বিটি প্রয়োজন, যদিও আপনার দৃষ্টিকোণ থেকে, অবজেক্ট এ এর বস্তু বি বাঁচে কি না সেদিকে নজর দেওয়া উচিত নয়। যেহেতু বস্তু A মনে করে অবজেক্ট B এর প্রয়োজনীয়, অবজেক্ট এ অবজেক্ট B কে আবর্জনা সংগ্রাহকের হাত থেকে রক্ষা করে যতক্ষণ অবজেক্ট এ জীবিত থাকে। তবে, যদি আপনি ইভেন্টটির গ্রাহক অবজেক্টটিকে দেওয়া সুরক্ষাটি না চান, তবে আপনি বলতে পারেন, একটি মেমরি ফাঁস হয়েছিল।
ইভেন্ট হ্যান্ডলারটিকে আলাদা করে আপনি এ জাতীয় ফুটো এড়াতে পারেন।
কীভাবে সিদ্ধান্ত নেবেন?
তবে, আপনার পুরো কোড-বেসে প্রচুর ইভেন্ট এবং ইভেন্ট হ্যান্ডলার রয়েছে। এর অর্থ কি, আপনার সর্বত্র ইভেন্ট হ্যান্ডলারদের আলাদা করা দরকার? উত্তরটি হ'ল যদি আপনার এটি করতে হয় তবে আপনার কোডবেসটি ভার্বোজের সাথে সত্যই কুরুচিপূর্ণ হবে।
আপনি কোনও বিচ্ছিন্ন ইভেন্ট হ্যান্ডলার প্রয়োজনীয় কিনা তা নির্ধারণ করতে আপনি বরং একটি সাধারণ ফ্লো চার্ট অনুসরণ করতে পারেন।
বেশিরভাগ সময়, আপনি ইভেন্ট গ্রাহক অবজেক্টটি ইভেন্ট প্রকাশকের অবজেক্টের মতোই গুরুত্বপূর্ণ এবং উভয়ই একই সময়ে থাকার কথা বলে মনে করছেন।
এমন একটি দৃশ্যের উদাহরণ যেখানে আপনাকে চিন্তার দরকার নেই
উদাহরণস্বরূপ, উইন্ডোর একটি বাটন ক্লিক ইভেন্ট।
এখানে ইভেন্টের প্রকাশক হলেন বাটন এবং ইভেন্টের গ্রাহক হলেন মেইন উইন্ডো। সেই ফ্লো চার্ট প্রয়োগ করে, একটি প্রশ্ন জিজ্ঞাসা করুন, মূল উইন্ডো (ইভেন্ট গ্রাহক) বোতামের আগে (ইভেন্ট প্রকাশক) মারা যাওয়ার কথা বলে? স্পষ্টত না। ঠিক আছে? এটি এমনকি কোনও অর্থবোধ করে না। তারপরে, ক্লিক ইভেন্ট হ্যান্ডলারটি আলাদা করার বিষয়ে কেন চিন্তা করবেন?
একটি ইভেন্ট হ্যান্ডলার বিচ্ছিন্নতা আবশ্যক যখন একটি উদাহরণ।
আমি একটি উদাহরণ প্রদান করব যেখানে গ্রাহক অবজেক্টটি প্রকাশক বস্তুর আগে মারা যাওয়ার কথা। বলুন, আপনার মেইন উইন্ডো "সামথিংহ্যাপডেন" নামে একটি ইভেন্ট প্রকাশ করে এবং আপনি একটি বাটন ক্লিক করে মূল উইন্ডো থেকে একটি শিশু উইন্ডো দেখান। শিশু উইন্ডোটি মূল উইন্ডোটির সেই ইভেন্টটিতে সদস্যতা নিয়েছে।
এবং, শিশু উইন্ডোটি মূল উইন্ডোটির একটি ইভেন্টে সদস্যতা নিয়েছে।
এই কোড থেকে, আমরা পরিষ্কারভাবে বুঝতে পারি যে মূল উইন্ডোতে একটি বোতাম আছে। সেই বোতামটি ক্লিক করা একটি শিশু উইন্ডো প্রদর্শন করে। সন্তানের উইন্ডোটি মূল উইন্ডো থেকে একটি ইভেন্ট শোনায়। কিছু করার পরে, ব্যবহারকারী সন্তানের উইন্ডোটি বন্ধ করে দেয়।
এখন, প্রবাহের চার্ট অনুসারে আমি সরবরাহ করেছি যদি আপনি কোন প্রশ্ন জিজ্ঞাসা করেন "ইভেন্ট উইন্ডোজ (মূল উইন্ডো) এর আগে চাইল্ড উইন্ডো (ইভেন্ট গ্রাহক) মারা গেছে বলে মনে করা হচ্ছে? উত্তরটি হ্যাঁ হওয়া উচিত। ঠিক? সুতরাং, ইভেন্ট হ্যান্ডলারটি বিচ্ছিন্ন করুন? আমি সাধারনত উইন্ডোর আনলোড হওয়া ইভেন্ট থেকে এটি করি।
থাম্বের একটি নিয়ম: যদি আপনার ভিউ (যেমন ডাব্লুপিএফ, উইনফর্ম, ইউডাব্লুপি, জ্যামারিন ফর্ম ইত্যাদি) ভিউমোডেলের কোনও ইভেন্টের সদস্যতা গ্রহণ করে, ইভেন্ট হ্যান্ডলারটি সর্বদা আলাদা করে রাখতে ভুলবেন না। কারণ একটি ভিউমোডেল সাধারণত দেখার চেয়ে দীর্ঘায়িত হয়। সুতরাং, যদি ভিউমোডেলটি ধ্বংস না হয় তবে সেই ভিউমোডেলের সাবস্ক্রাইব করা ইভেন্টের কোনও দৃশ্য মেমরিতে থাকবে, যা ভাল নয়।
মেমরির প্রোফাইলার ব্যবহার করে ধারণাটির প্রমাণ।
আমরা মেমরির প্রোফাইলার দিয়ে ধারণাটি বৈধ করতে না পারলে এটি খুব মজাদার হবে না। আমি এই পরীক্ষায় জেটব্রেইন ডটমেমরি প্রোফাইলার ব্যবহার করেছি।
প্রথমত, আমি মেইন উইন্ডো চালিয়েছি, যা এটির মতো দেখায়:
তারপরে, আমি একটি স্মৃতি স্ন্যাপশট নিয়েছিলাম। তারপরে আমি বোতামটি 3 বার ক্লিক করেছি । তিন সন্তানের উইন্ডো প্রদর্শিত হয়েছে। আমি সেই সমস্ত উইন্ডোটি বন্ধ করে ফেলেছি এবং ডটমেমরি প্রোফাইলারে ফোর্স জিসি বোতামটি ক্লিক করেছি যাতে আবর্জনা সংগ্রাহককে ডেকে আনা হয় তা নিশ্চিত করতে। তারপরে, আমি আরেকটি স্মৃতি স্ন্যাপশট নিয়েছি এবং এটি তুলনা করেছি। দেখ! আমাদের ভয় সত্য ছিল। শিশু উইন্ডোটি আবর্জনা সংগ্রাহকরা বন্ধ করার পরেও সংগ্রহ করেননি। কেবল তা-ই নয়, চাইল্ড উইন্ডো অবজেক্টের জন্য ফাঁস হওয়া অবজেক্টের গণনাটিও " 3 " দেখানো হয়েছে (3 টি বাচ্চা উইন্ডো দেখানোর জন্য আমি বোতামটি 3 বার ক্লিক করেছি)।
ঠিক আছে, তারপরে, আমি নীচের চিত্রের মতো ইভেন্ট হ্যান্ডলারটিকে বিযুক্ত করেছি।
তারপরে, আমি একই পদক্ষেপগুলি সম্পাদন করেছি এবং মেমরি প্রোফাইলারটি পরীক্ষা করেছি। এবার, বাহ! আর মেমরি ফুটো নেই।