আবর্জনা সংগ্রহ থেকে নিষ্পত্তি আলাদা করা গুরুত্বপূর্ণ। এগুলি সম্পূর্ণ পৃথক জিনিস, এক পয়েন্টের সাথে সাধারণ যা আমি এক মিনিটে আসব।
Dispose
, আবর্জনা সংগ্রহ এবং চূড়ান্তকরণ
আপনি যখন কোনও using
বিবৃতি লিখেন , এটি চেষ্টা / অবশেষে অবরুদ্ধ করার জন্য কেবল সিনট্যাকটিক চিনি হয় যাতে বিবৃতিটির শিরোনামের Dispose
কোডটি using
একটি ব্যতিক্রম ছুঁড়ে মারলেও তাকে বলা হয়। এর অর্থ এই নয় যে অবজেক্টটি ব্লকের শেষে সংগ্রহ করা আবর্জনা।
নিষ্পত্তি হ'ল পরিচালনাহীন সংস্থানসমূহ ( স্মৃতিবিহীন সংস্থানসমূহ) সম্পর্কে। এগুলি ইউআই হ্যান্ডলগুলি, নেটওয়ার্ক সংযোগগুলি, ফাইল হ্যান্ডলগুলি ইত্যাদি হতে পারে এগুলি সীমিত সংস্থানসমূহ, সুতরাং আপনি সাধারণত যত তাড়াতাড়ি সম্ভব এগুলি মুক্তি দিতে চান। IDisposable
যখনই আপনার টাইপটি নিয়ন্ত্রণহীন সংস্থানটি "মালিকানাধীন" হয় সরাসরি প্রয়োগ করা উচিত (সাধারণত একটি মাধ্যমে IntPtr
) বা অপ্রত্যক্ষভাবে (যেমন একটি Stream
, একটি SqlConnection
ইত্যাদির মাধ্যমে )।
জঞ্জাল সংগ্রহ কেবল মেমরি সম্পর্কে - একটি সামান্য মোচড় দিয়ে। আবর্জনা সংগ্রহকারী এমন সামগ্রী খুঁজে পেতে সক্ষম হন যা আর উল্লেখ করা যায় না এবং সেগুলি মুক্ত করে। এটি সর্বদা আবর্জনার সন্ধান করে না - কেবলমাত্র যখন এটি সনাক্ত করে যে এটির প্রয়োজন রয়েছে (উদাহরণস্বরূপ যদি স্তূপের একটি "প্রজন্ম" স্মৃতিশক্তি থেকে সরে যায়)।
সুতা হয় চূড়ান্ত । আবর্জনা সংগ্রহকারী এমন অবজেক্টের একটি তালিকা রাখে যা আর অ্যাক্সেসযোগ্য নয়, তবে যার একটি ফাইনালাইজার রয়েছে ( ~Foo()
সি # তে লেখা আছে , কিছুটা বিভ্রান্তিকরভাবে - সেগুলি সি ++ ধ্বংসকারীদের মতো কিছুই নয়)। এটি এই বিষয়গুলিতে চূড়ান্তকরণকারীদের চালায়, কেবল যদি তাদের স্মৃতিশক্তি মুক্ত হওয়ার আগে তাদের অতিরিক্ত ক্লিনআপ করার প্রয়োজন হয়।
ফাইনালাইজারগুলি প্রায়শই সর্বদা সম্পদ পরিষ্কার করতে ব্যবহৃত হয় যেখানে প্রকারের ব্যবহারকারী এটি সুশৃঙ্খলভাবে নিষ্পত্তি করতে ভুলে গেছে। সুতরাং আপনি যদি কিছু খুলেন FileStream
তবে কল করতে ভুলে যান Dispose
বা Close
, ফাইনালাইজারটি শেষ পর্যন্ত আপনার জন্য অন্তর্নিহিত ফাইল হ্যান্ডেল প্রকাশ করবে। একটি লিখিত প্রোগ্রামে, চূড়ান্তকারীদের আমার মতে প্রায় কখনওই গুলি চালানো উচিত নয়।
একটি ভেরিয়েবল সেট করা হচ্ছে null
ভেরিয়েবল নির্ধারণের জন্য একটি ছোট পয়েন্ট null
- আবর্জনা সংগ্রহের প্রয়োজনে এটি কখনই প্রয়োজন হয় না। এটি সদস্যের পরিবর্তনশীল হলে আপনি কখনও কখনও এটি করতে চাইতে পারেন, যদিও আমার অভিজ্ঞতায় এটি কোনও জিনিসের "অংশ" এর পক্ষে আর প্রয়োজন হয় না। যখন এটি স্থানীয় পরিবর্তনশীল হয়, আপনি কখন আবার কোনও উল্লেখ ব্যবহার করতে যাবেন না তা জানতে জেআইটি সাধারণত যথেষ্ট স্মার্ট (রিলিজ মোডে) থাকে। উদাহরণ স্বরূপ:
StringBuilder sb = new StringBuilder();
sb.Append("Foo");
string x = sb.ToString();
// The string and StringBuilder are already eligible
// for garbage collection here!
int y = 10;
DoSomething(y);
// These aren't helping at all!
x = null;
sb = null;
// Assume that x and sb aren't used here
আপনি যখন লুপে থাকবেন তখন এক সময় যেখানে স্থানীয় ভেরিয়েবল সেট করা মূল্যবান হতে পারে এবং null
লুপের কয়েকটি শাখাকে ভেরিয়েবল ব্যবহার করা দরকার তবে আপনি জানেন যে আপনি এমন একটি পর্যায়ে পৌঁছেছেন যা আপনি করেননি। উদাহরণ স্বরূপ:
SomeObject foo = new SomeObject();
for (int i=0; i < 100000; i++)
{
if (i == 5)
{
foo.DoSomething();
// We're not going to need it again, but the JIT
// wouldn't spot that
foo = null;
}
else
{
// Some other code
}
}
আইডিস্পোজেবল / ফাইনালাইজারগুলি কার্যকর করা
সুতরাং, আপনার নিজের ধরণের চূড়ান্তকরণগুলি প্রয়োগ করা উচিত? প্রায় অবশ্যই না। যদি আপনি কেবল অপ্রত্যক্ষভাবে নিয়ন্ত্রণহীন সংস্থানগুলি ধরে রাখেন (উদাহরণস্বরূপ আপনি FileStream
সদস্যের পরিবর্তনশীল হিসাবে একটি পেয়েছেন ) তবে আপনার নিজের চূড়ান্তর সংযোজন সাহায্য করবে না: আপনার বস্তুটি যখন স্ট্রিমটি আবশ্যক তখন অবশ্যই আবর্জনা সংগ্রহের জন্য উপযুক্ত হবে, সুতরাং আপনি কেবল নির্ভর করতে পারবেন FileStream
একটি চূড়ান্তকরণকারী (যদি প্রয়োজন হয় - এটি অন্য কোনও কিছুতে উল্লেখ করতে পারে) having আপনি একটি অপরিচালিত রিসোর্স রাখা চান তাহলে "প্রায়" সরাসরি SafeHandle
আপনার বন্ধু - এটা সময়ের সাথে সাথে পেতে যাচ্ছে একটি বিট লাগে, তবে এটি আপনাকে করব মানে প্রায় একটি finalizer আবার লিখতে প্রদান করার প্রয়োজন নেই । আপনার যদি কেবল কোনও উত্স (এ IntPtr
) এর সত্যিকারের সরাসরি হ্যান্ডেল থাকে তবে আপনার কেবলমাত্র একটি ফাইনালাইজারের প্রয়োজন হবে এবং আপনার দিকে যাওয়ার চেষ্টা করা উচিতSafeHandle
যত দ্রুত সম্ভব. (সেখানে দুটি লিঙ্ক রয়েছে - উভয়ই আদর্শভাবে পড়ুন))
জো ডাফির চূড়ান্তকরণকারী এবং আইডিস্পোজেবল (প্রচুর স্মার্ট লোকের সাথে সহ-লিখিত) এর চারপাশে একটি দীর্ঘ নির্দেশিকা রয়েছে যা পাঠযোগ্য । এটি আপনার সচেতন হওয়া উচিত যে আপনি যদি আপনার ক্লাসগুলি সিল করেন তবে এটি জীবনকে অনেক সহজ করে তোলে: যখন আপনার শ্রেণিটি উত্তরাধিকারের জন্য তৈরি করা হয় তখনই Dispose
নতুন ভার্চুয়াল Dispose(bool)
পদ্ধতি ইত্যাদি কল করতে ওভাররাইড করার ধরণটি প্রাসঙ্গিক।
এটি কিছুটা দৌড়ঝাঁপ হয়েছে, তবে দয়া করে আপনাকে কিছু চাই যেখানে স্পষ্টতা জিজ্ঞাসা করুন :)