c# - জিসি কলেক্ট করার সময় কি গ্রহনযোগ্য?



.net garbage-collection (19)

সাধারণ পরামর্শ হল যে আপনি GC.Collect কল করবেন না। আপনার কোড থেকে সংগ্রহ করুন, তবে এই নিয়মটির ব্যতিক্রম কী?

আমি কেবলমাত্র কয়েকটি বিশেষ ক্ষেত্রেই মনে করতে পারি যেখানে এটি একটি আবর্জনা সংগ্রহকে জোরদার করতে পারে।

একটি উদাহরণ যে স্প্রিংস মনে রাখা একটি পরিষেবা, যা অন্তর্বর্তী সময়ে জেগে ওঠে, কিছু কাজ সম্পাদন করে, এবং তারপর দীর্ঘ সময়ের জন্য ঘুমায়। এই ক্ষেত্রে, দ্রুত-থেকে-নিষ্ক্রিয় প্রক্রিয়াটিকে প্রয়োজনীয়তার চেয়ে বেশি মেমরি ধরে রাখার জন্য একটি সংগ্রহকে জোরদার করা একটি ভাল ধারণা হতে পারে।

GC.Collect কল করতে গ্রহণযোগ্য যেখানে অন্য কোন ক্ষেত্রে আছে?


Answers

আপনি GC.Collect () কে কল করতে পারেন যখন আপনি অ্যাপ্লিকেশনটির প্রকৃতি সম্পর্কে কিছু জানেন, আবর্জনা সংগ্রাহক তা করেন না। এটা চিন্তা করার প্রলুব্ধকর যে, লেখক হিসাবে, এটি খুব সম্ভবত। যাইহোক, সত্যটি একটি প্রশংসনীয় ভাল-লিখিত এবং পরীক্ষিত বিশেষজ্ঞ সিস্টেমের জিসি পরিমাণ, এবং এটি খুব বিরল আপনি নিম্ন স্তরের কোড পথগুলি সম্পর্কে কিছু জানেন যা এটি নয়।

সেরা উদাহরণ যেখানে আমি কিছু অতিরিক্ত তথ্য থাকতে পারি তা হল একটি অ্যাপ্লিকেশন যা নিষ্ক্রিয় সময়ের এবং খুব ব্যস্ত সময়ের মধ্যে চক্র। ব্যস্ত সময়ের জন্য সর্বোত্তম পারফরমেন্সটি আপনি চান এবং তাই কিছু পরিষ্কার করার জন্য নিষ্ক্রিয় সময়টি ব্যবহার করতে চান।

যাইহোক, বেশিরভাগ সময়ই জিসি এইভাবে করতে যথেষ্ট স্মার্ট।


যদি আপনার বিশ্বাসযোগ্য কারণ থাকে যে বস্তুর একটি উল্লেখযোগ্য সেট - বিশেষ করে যাদের আপনি 1 এবং 2 বছরগুলিতে সন্দেহ করতে পারেন - এখন আবর্জনা সংগ্রহের যোগ্য, এবং এখন ছোট পারফরম্যান্সের কারণে সংগ্রহ করার জন্য উপযুক্ত সময় হবে ।

এটির একটি ভাল উদাহরণ যদি আপনি কেবল একটি বড় ফর্ম বন্ধ করেছেন। আপনি জানেন যে সমস্ত UI নিয়ন্ত্রণগুলি এখন আবর্জনা সংগ্রহ করা যেতে পারে এবং ফরমটি বন্ধ হওয়ার ক্ষেত্রে খুব অল্প বিরতি সম্ভবত ব্যবহারকারীর কাছে লক্ষ্যযোগ্য হবে না।

আপডেট 2.7.2018

.NET 4.5 হিসাবে - GCLatencyMode.LowLatency এবং GCLatencyMode.SustainedLowLatency । এই মোডগুলির মধ্যে যে কোনও প্রবেশ বা প্রবেশ করার সময়, আপনি GC.Collect(2, GCCollectionMode.Forced) সাথে একটি সম্পূর্ণ GC GC.Collect(2, GCCollectionMode.Forced)

.NET 4.6 হিসাবে - GC.TryStartNoGCRegion পদ্ধতি রয়েছে (শুধুমাত্র GCLatencyMode.NoGCRegion মান GCLatencyMode.NoGCRegion সেট করতে ব্যবহৃত)। এটি নিজে থেকেই, সম্পূর্ণ মেমরি মুক্ত করার প্রচেষ্টাতে একটি সম্পূর্ণ ব্লকিং আবর্জনা সংগ্রহ সঞ্চালন করতে পারে, তবে নির্দিষ্ট সময়ের জন্য আমরা জিসিকে অস্বীকৃতি জানাচ্ছি, আমি আগে এবং পরে পূর্ণ জিসি সঞ্চালনেরও একটি ভাল ধারণা।

উত্স: মাইক্রোসফ্ট প্রকৌশলী বেন ওয়াটসন এর লেখা : হাই পারফরম্যান্স .নেট কোড , ২ য় এড। 2018।

দেখুন:


সংক্ষিপ্ত উত্তর: না!


আমি GC.Collect ব্যবহার GC.Collect যখন কেবল ক্রুড পারফরম্যান্স / প্রোফাইলেলার পরীক্ষার রিগ্স লেখা হয়; অর্থাৎ আমি পরীক্ষা করার কোড দুটি (বা আরো) ব্লক আছে - কিছু ভালো:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestA(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestB(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
...

সুতরাং TestA() এবং TestB() একই রকম অবস্থায় চালানো হয় - অর্থাৎ TestB() করে না শুধুমাত্র TestA এটি টিপিং পয়েন্টের খুব কাছাকাছি রেখে যায়।

একটি ক্লাসিক উদাহরণটি একটি সহজ কনসোল এক্সে (উদাহরণস্বরূপ এখানে পোস্ট করার জন্য একটি Main পদ্ধতির StringBuilder ) যা StringBuilder স্ট্রিং কনক্যাটেনেশন এবং StringBuilder মধ্যে পার্থক্য দেখায়।

যদি আমার কিছুটা সুনির্দিষ্ট প্রয়োজন হয়, তবে এটি দুটি সম্পূর্ণ স্বাধীন পরীক্ষা হবে - তবে প্রায়ই এটি যথেষ্ট হয় যদি আমরা পরীক্ষার সময় জি.সি.কে কমিয়ে আনতে (অথবা সাধারনভাবে) আচরণের জন্য রুক্ষ অনুভূতি পেতে চাই।

উত্পাদন কোড সময়? আমি এখনও এটি ব্যবহার করতে হবে; -পি


যদি আপনি 4.5 এর চেয়ে কম। এর সংস্করণ ব্যবহার করেন তবে ম্যানুয়াল সংগ্রহ অনিবার্য হতে পারে (বিশেষত যদি আপনি অনেকগুলি বড় বস্তু নিয়ে কাজ করছেন)।

এই লিঙ্কটি কেন বর্ণনা করে:

https://blogs.msdn.microsoft.com/dotnet/2011/10/03/large-object-heap-improvements-in-net-4-5/


GC.Collect () কে কল করার জন্য একটি দরকারী জায়গা আপনি একটি মেমরি লিক তৈরি করছেন না তা যাচাই করার জন্য একটি ইউনিট পরীক্ষায় (উদাহরণস্বরূপ, যদি আপনি ওয়েক রেফারেন্স বা শর্তাধীন উইক্যাটেবল, গতিশীলভাবে জেনারেট কোড, ইত্যাদি সহ কিছু করছেন)।

উদাহরণস্বরূপ, আমার মত কয়েকটি পরীক্ষা আছে:

WeakReference w = CodeThatShouldNotMemoryLeak();
Assert.IsTrue(w.IsAlive);
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.IsFalse(w.IsAlive);

এটি যুক্তিযুক্ত করা যেতে পারে যে ওয়েক রেফারেন্সগুলি ব্যবহার করা এবং নিজের মধ্যে একটি সমস্যা, তবে মনে হচ্ছে যে যদি আপনি এমন আচরণ তৈরি করেন যা এমন আচরণের উপর নির্ভর করে তবে GC.Collect () কে কল করা এই কোডটি যাচাই করার একটি ভাল উপায়।


এটি প্রশ্নটির সাথে প্রাসঙ্গিক নয়, তবে XSLT- র জন্য .NET (XSLCompiledTranform) রূপান্তরিত হয় তবে আপনার কোনও বিকল্প নেই। আরেকটি প্রার্থী এমএসএইচএমএল নিয়ন্ত্রণ।


আমি অ্যারে এবং তালিকা কিছু কর্মক্ষমতা পরীক্ষার করছেন:

private static int count = 100000000;
private static List<int> GetSomeNumbers_List_int()
{
    var lstNumbers = new List<int>();
    for(var i = 1; i <= count; i++)
    {
        lstNumbers.Add(i);
    }
    return lstNumbers;
}
private static int[] GetSomeNumbers_Array()
{
    var lstNumbers = new int[count];
    for (var i = 1; i <= count; i++)
    {
        lstNumbers[i-1] = i + 1;
    }
    return lstNumbers;
}
private static int[] GetSomeNumbers_Enumerable_Range()
{
    return  Enumerable.Range(1, count).ToArray();
}

static void performance_100_Million()
{
    var sw = new Stopwatch();

    sw.Start();
    var numbers1 = GetSomeNumbers_List_int();
    sw.Stop();
    //numbers1 = null;
    //GC.Collect();
    Console.WriteLine(String.Format("\"List<int>\" took {0} milliseconds", sw.ElapsedMilliseconds));

    sw.Reset();
    sw.Start();
    var numbers2 = GetSomeNumbers_Array();
    sw.Stop();
    //numbers2 = null;
    //GC.Collect();
    Console.WriteLine(String.Format("\"int[]\" took {0} milliseconds", sw.ElapsedMilliseconds));

    sw.Reset();
    sw.Start();
//getting System.OutOfMemoryException in GetSomeNumbers_Enumerable_Range method
    var numbers3 = GetSomeNumbers_Enumerable_Range();
    sw.Stop();
    //numbers3 = null;
    //GC.Collect();

    Console.WriteLine(String.Format("\"int[]\" Enumerable.Range took {0} milliseconds", sw.ElapsedMilliseconds));
}

এবং আমি GetOomeNumbers_Enumerable_Range পদ্ধতিতে OutOfMemoryException খুঁজে পেয়েছি OutOfMemoryException হ'ল OutOfMemoryException হ্রাস করা হল:

numbers = null;
GC.Collect();

একটি মেমরি বিভাজক সমাধান হিসাবে। একটি মেমরি প্রবাহে অনেক তথ্য লেখার সময় আমি একটি মেমরি ব্যতিক্রম খুঁজে পেয়েছিলাম (একটি নেটওয়ার্ক প্রবাহ থেকে পড়া)। তথ্য 8K অংশে লিখিত ছিল। 128M পৌঁছানোর পরে অনেক মেমরি উপলব্ধ ছিল তবে ব্যতিক্রম ছিল (কিন্তু এটি ভেঙে ফেলা হয়েছিল)। কলিং জিসি। সংগ্রহ () সমস্যা সমাধান। আমি ফিক্স পরে 1G উপর হ্যান্ডেল করতে সক্ষম ছিল।



জিসি কল করার জন্য একটি ভাল কারণ ক্ষুদ্র মেমরি সহ ছোট এআরএম কম্পিউটারগুলিতে রয়েছে, যেমন রাস্পবেরি পিআই (মোনো দিয়ে চলমান)। যদি অনির্ধারিত মেমরি টুকরা সিস্টেম RAM এর বেশি ব্যবহার করে তবে লিনাক্স OS অস্থির হতে পারে। মেমরি ওভারফ্লো সমস্যাগুলি পরিত্রাণ পেতে প্রতি সেকেন্ডে (!) আমাকে জিসি কল করতে হবে এমন একটি অ্যাপ্লিকেশন আছে।

আরেকটি ভাল সমাধান বস্তু নিষ্পত্তি করা হয় যখন তারা আর প্রয়োজন হয় না। দুর্ভাগ্যবশত এটি অনেক ক্ষেত্রে এত সহজ নয়।


এক ক্ষেত্রে যখন আপনি WeakReference ব্যবহার করে ইউনিট পরীক্ষা কোডের চেষ্টা করছেন।


কিছু পরিস্থিতিতে আছে যেখানে এটি দুঃখিত চেয়ে ভাল নিরাপদ।

এখানে একটি পরিস্থিতি।

আইএল পুনর্লিখনগুলি ব্যবহার করে C # এ একটি unmanaged DLL লেখার পক্ষে সম্ভব (কারণ সেখানে এমন পরিস্থিতি রয়েছে যেখানে এটি প্রয়োজনীয়)।

এখন ধরুন, উদাহরণস্বরূপ, DLL ক্লাস স্তরে বাইটের একটি অ্যারে তৈরি করে - কারণ এক্সপোর্ট করা ফাংশনগুলির মধ্যে এমন অ্যাক্সেসের প্রয়োজন হয়। DLL আনলোড করা হলে কি হবে? আবর্জনা সংগ্রাহক স্বয়ংক্রিয়ভাবে যে সময়ে আহ্বান করা হয়? আমি জানি না, কিন্তু একটি unmanaged DLL হচ্ছে এটি সম্পূর্ণরূপে সম্ভব জিসি বলা হয় না। এবং এটি বলা হয় না যদি এটি একটি বড় সমস্যা হবে। যখন ডিএলএল আনলোড করা হয় তখনও আবর্জনা সংগ্রাহক হবে - তাহলে কোন সম্ভাব্য আবর্জনা সংগ্রহের জন্য কে দায়ী হবে এবং তারা কীভাবে এটি করবে? সি # এর আবর্জনা সংগ্রাহক নিয়োগ করা ভাল। ক্লিনআপ ফাংশন (DLL ক্লায়েন্টে উপলব্ধ) আছে যেখানে ক্লাস স্তরের ভেরিয়েবলগুলি নিল এবং ক্যবাজার সংগ্রাহক বলা হয়।

দুঃখিত চেয়ে ভাল নিরাপদ.


আমি এখনও এই সম্পর্কে বেশ অনিশ্চিত। আমি একটি অ্যাপ্লিকেশন সার্ভারে 7 বছর ধরে কাজ করছি। আমাদের বড় ইনস্টলেশনের ব্যবহার 24 গিগাবাইট রাম। তার উচ্চাভিলাষী Multithreaded, এবং GC.Collect জন্য সব কল () সত্যিই ভয়ঙ্কর কর্মক্ষমতা সমস্যা মধ্যে দৌড়ে।

অনেক তৃতীয় পক্ষের সামগ্রী GC.Collect () ব্যবহার করে যখন তারা মনে করেছিল যে এটি এখনই এটি করার জন্য চতুর। সুতরাং এক্সেল-রিপোর্টগুলির একটি সহজ গুচ্ছ একটি মিনিটের বেশ কয়েকবার সমস্ত থ্রেডের জন্য অ্যাপ সার্ভারকে অবরোধ করে।

GC.Collect () কলগুলি সরিয়ে দেওয়ার জন্য আমাদের সমস্ত তৃতীয় পক্ষের উপাদানগুলিকে পুনরায় প্রতিক্রিয়া জানাতে হয়েছিল, এবং এটি করার পরে সকলেই জরিমানা করে।

কিন্তু আমি Win32 এ সার্ভারগুলি চালাচ্ছি, এবং এখানে আমি OutOfMemoryException পাওয়ার পরে GC.Collect () এর ভারী ব্যবহার করতে শুরু করেছি।

কিন্তু আমিও এটি সম্পর্কে নিশ্চিত নই, কারণ আমি প্রায়শই লক্ষ্য করেছি, যখন আমি 32 বিট-তে একটি OOM পাই, এবং আমি আবার একই অপারেশন চালানোর জন্য আবার চেষ্টা করি, জিসি। কলকটি (কল) ছাড়া, এটা ঠিক কাজ করে।

এক জিনিস আমি আশ্চর্য যে OOM ব্যতিক্রম নিজেই ... যদি আমি নেট ফ্রেমওয়ার্ক লিখে থাকতাম, এবং আমি একটি মেমরি ব্লক বরাদ্দ করতে পারি না, আমি GC.Collect (), ডিফ্র্যাগ মেমরি (??) ব্যবহার করব, আবার চেষ্টা করুন , এবং যদি আমি এখনও একটি মুক্ত মেমরি ব্লক খুঁজে পাচ্ছি না, তাহলে আমি OOM-ব্যতিক্রমটি নিক্ষেপ করব।

অথবা কমপক্ষে কনফিগারযোগ্য বিকল্প হিসাবে এই আচরণটি তৈরি করুন, GC.Collect এর সাথে পারফরম্যান্স সমস্যাগুলির ত্রুটিগুলির কারণে।

এখন আমার এপ্লিকেশনে এটিকে অনেকগুলি কোড "সমস্যা সমাধান" করার জন্য আছে:

public static TResult ExecuteOOMAware<T1, T2, TResult>(Func<T1,T2 ,TResult> func, T1 a1, T2 a2)
{

    int oomCounter = 0;
    int maxOOMRetries = 10;
    do
    {
        try
        {
            return func(a1, a2);
        }
        catch (OutOfMemoryException)
        {
            oomCounter++;
            if (maxOOMRetries > 10)
            {
                throw;
            }
            else
            {
                Log.Info("OutOfMemory-Exception caught, Trying to fix. Counter: " + oomCounter.ToString());
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(oomCounter * 10));
                GC.Collect();
            }
        }
    } while (oomCounter < maxOOMRetries);

    // never gets hitted.
    return default(TResult);
}

(উল্লেখ্য যে থ্রেড। নিদ্রা (আচরণ) আচরণটি আসলেই অ্যাপ স্পেশাল আচরণ, কারণ আমরা একটি ওআরএম ক্যাশিং পরিষেবা চালাচ্ছি, এবং যদি র্যামটি কিছু পূর্বনির্ধারিত মান অতিক্রম করে তবে পরিষেবাটি সমস্ত ক্যাশেড বস্তু মুক্ত করার জন্য কিছু সময় নেয়। সুতরাং এটি অপেক্ষা করে কয়েক সেকেন্ডের মধ্যে প্রথমবার, এবং OOM প্রতিটি occurence অপেক্ষা সময় বৃদ্ধি করেনি।)


যেহেতু ছোট বস্তু হিপ (SOH) এবং বড় বস্তু হিপ (LOH)

আমরা SOP তে ডি-রেফারেন্স বস্তুটি সাফ করতে GC.Collect () কল করতে পারি এবং জীবন্ত বস্তুকে পরবর্তী প্রজন্মের দিকে সরাতে পারি।

ইন। নেট 4 .5, আমরা বড় লোকেশনহাপ কম্প্যাকশনমোড ব্যবহার করে LOH কম্প্যাক্ট করতে largeobjectheapcompactionmode


বড় 24/7 বা 24/6 সিস্টেমে - বার্তাগুলিতে প্রতিক্রিয়াশীল সিস্টেমগুলি, RPC অনুরোধগুলি বা অবিরত ডাটাবেস বা প্রক্রিয়াটি প্রক্রিয়া করে - এটি মেমরি লিকগুলি সনাক্ত করার উপায় আছে। এর জন্য, আমি অস্থায়ীভাবে কোনও প্রক্রিয়াকরণ স্থগিত করার জন্য এবং সম্পূর্ণ আবর্জনা সংগ্রহ সঞ্চালনের জন্য আবেদনটিতে একটি প্রক্রিয়া যুক্ত করতে ঝোঁক। এটি সিস্টেমে একটি কোমল অবস্থানে রাখে যেখানে মেমরি অবশিষ্ট থাকে বৈধভাবে দীর্ঘস্থায়ী মেমরি (ক্যাশে, কনফিগারেশন, এবং সি।) বা অন্যথায় 'ফুটো' (বস্তুগুলি যা প্রত্যাশিত না হয় বা মূলত মূল হতে চান তবে আসলেই হয়) রাখে।

এই প্রক্রিয়াটি মেমরি ব্যবহারের প্রোফাইলটিকে অনেক সহজ করে তোলে কারণ রিপোর্টগুলি সক্রিয় প্রক্রিয়াকরণ থেকে শোরগোলের সাথে ক্লাউড করা হবে না।

আপনি সব আবর্জনা পেতে নিশ্চিত করার জন্য, আপনি দুটি সংগ্রহ সঞ্চালন করতে হবে:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

প্রথম সংগ্রহটি চূড়ান্ত সিদ্ধান্তগুলির সাথে চূড়ান্ত করার কোনও কারণ সৃষ্টি করবে (তবে আসলে আবর্জনাগুলি এই বস্তুগুলি সংগ্রহ করে না)। দ্বিতীয় জিসি আবর্জনা এই চূড়ান্ত বস্তু সংগ্রহ করবে।


আপনার উদাহরণে, আমি মনে করি GC.Collect কলিং সমস্যা নয়, বরং একটি ডিজাইন সমস্যা রয়েছে।

আপনি যদি বিরতিতে জাগতে যাচ্ছেন, (সেট টাইমস) তবে আপনার প্রোগ্রামটিকে একক এক্সিকিউশন (একবার টাস্কটি সম্পাদন করুন) করার জন্য তৈরি করা উচিত এবং তারপরে সমাপ্ত করা হবে। তারপরে, আপনি নির্ধারিত সময়ের মধ্যে চালানোর জন্য নির্ধারিত কার্য হিসাবে প্রোগ্রামটিকে সেট আপ করুন।

এই ভাবে, আপনি GC.Collect কল করে নিজেকে উদ্বিগ্ন করতে হবে না, (যা আপনাকে খুব কমই করতে হবে, যা করতে হবে)।

যে বলেন, রিকো Mariani এই বিষয়ে একটি মহান ব্লগ পোস্ট আছে, যা এখানে পাওয়া যাবে:

http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx


GC.Collect () ব্যবহার করে এটিকে খুব ব্যয়বহুল করে তোলার চেষ্টা করা উচিত। এখানে একটি উদাহরণ:

        public void ClearFrame(ulong timeStamp)
    {
        if (RecordSet.Count <= 0) return;
        if (Limit == false)
        {
            var seconds = (timeStamp - RecordSet[0].TimeStamp)/1000;
            if (seconds <= _preFramesTime) return;
            Limit = true;
            do
            {
                RecordSet.Remove(RecordSet[0]);
            } while (((timeStamp - RecordSet[0].TimeStamp) / 1000) > _preFramesTime);
        }
        else
        {
            RecordSet.Remove(RecordSet[0]);

        }
        GC.Collect(); // AVOID
    }

পরীক্ষার ফলাফল: CPU ব্যবহার 12%

আপনি এই পরিবর্তন যখন:

        public void ClearFrame(ulong timeStamp)
    {
        if (RecordSet.Count <= 0) return;
        if (Limit == false)
        {
            var seconds = (timeStamp - RecordSet[0].TimeStamp)/1000;
            if (seconds <= _preFramesTime) return;
            Limit = true;
            do
            {
                RecordSet[0].Dispose(); //  Bitmap destroyed!
                RecordSet.Remove(RecordSet[0]);
            } while (((timeStamp - RecordSet[0].TimeStamp) / 1000) > _preFramesTime);
        }
        else
        {
            RecordSet[0].Dispose(); //  Bitmap destroyed!
            RecordSet.Remove(RecordSet[0]);

        }
        //GC.Collect();
    }

পরীক্ষার ফলাফল: CPU ব্যবহার 2-3%


C # তে, বেস বর্গের 'কন্সট্রাকটর ডেরিভেড ক্লাস' কন্সট্রকটারের আগে রান করে, তাই সম্ভাব্য-বর্ধিত ভার্চুয়াল সদস্যের মধ্যে প্রাপ্ত হওয়া কোনও বর্গভুক্ত শ্রেণির যে কোনও উদাহরণ ক্ষেত্রগুলি এখনও প্রবর্তিত হয় না।

মনে রাখবেন যে এটি আপনাকে সতর্কতা প্রদানের জন্য একটি সতর্কতা এবং এটি ঠিক আছে তা নিশ্চিত করুন। এই দৃশ্যকল্পটির জন্য প্রকৃত ব্যবহার-কেস রয়েছে, আপনি কেবলমাত্র ভার্চুয়াল সদস্যের আচরণকে নথিবদ্ধ করতে হবে যে এটি নিচের কোনও শ্রেণিবদ্ধ শ্রেণিতে ঘোষিত কোনও উদাহরণ ক্ষেত্র ব্যবহার করতে পারে না যেখানে কন্সট্রাকটর এটি কল করছে।





c# .net garbage-collection