ধ্বংসকারীদের জন্য আবর্জনা সংগ্রহকারী আচরণ


9

আমার একটি সাধারণ ক্লাস রয়েছে যা নীচে হিসাবে সংজ্ঞায়িত হয়েছে।

public class Person
{
    public Person()
    {

    }

    public override string ToString()
    {
        return "I Still Exist!";
    }

    ~Person()
    {
        p = this;

    }
    public static Person p;
}

প্রধান পদ্ধতিতে

    public static void Main(string[] args)
    {
        var x = new Person();
        x = null;

        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Person.p == null);

    }

আবর্জনা সংগ্রাহককে পার্সন.পি-এর মূল উল্লেখ করা উচিত এবং কখন ধ্বংসকারীকে ডাকা হবে?


প্রথম: C # এর একটি বিনাশকারী একটি হতে ment হয় finalizer । দ্বিতীয়: আপনার সিঙ্গলটন-দৃষ্টান্তটি চূড়ান্ত হওয়ার সাথে সাথে সেট করা খুব খারাপ ধারণা বলে মনে হচ্ছে । তৃতীয়: কী Person1? আমি শুধু দেখতে Person। শেষ: চূড়ান্তকরণকারীরা কীভাবে কাজ করে তার জন্য ডকস.মাইক্রোসফট.ডটনেট / সিএসআরপি / প্রোগ্রামগ্রামিং-গাইড দেখুন
হিমব্রুমবিয়ার

@ হিমব্র্যামবিয়ার Person1আসলে টাইপও Personঠিক করেছেন।
পরিমল রাজ

@ হিমব্রোমবিয়ার এটি আসলে একটি সাক্ষাত্কারের প্রশ্ন ছিল, এখন আমার বোঝাপড়া অনুসারে, সিজি.ক্ল্যাক্টের উচিত ছিল ধ্বংসাত্মককে ডাকতে হবে কিন্তু তা হয়নি।
পরিমল রাজ

2
(1) আপনি যদি ফিনিয়ালাইজারের ভিতরে অবজেক্টটিকে চূড়ান্ত করা হচ্ছে তার পুনরায় উল্লেখ করেন, তবে সেই রেফারেন্সটি কোনও রুট থেকে আর পৌঁছানো সম্ভব না হওয়া অবধি এটি সংগ্রহ করা যাবে না (সুতরাং এটি এর আবর্জনা সংগ্রহের বিলম্বের প্রভাব ফেলে)। (২) চূড়ান্তরূপে যখন বলা হয় তখন যে বিন্দুটি অনুমানযোগ্য তা নয়।
ম্যাথু ওয়াটসন

@HimBromBeere এবং আমি Console.WriteLine Person.p এ ব্রেকপয়েন্ট করা পর্যন্ত নাল হিসেবে এর আসছে নির্বিশেষে GC.Collectকল
পরিমল রাজ

উত্তর:


13

আপনি এখানে যে জিনিসটি অনুপস্থিত xতা হ'ল সংকলকটি আপনার চলকটির আধ্যাত্মিক পদ্ধতির সমাপ্তির অবধি প্রসারিত করবে যা এটি সংজ্ঞায়িত করা হয়েছে - এটি কেবল সংকলকটি কিছু করে - তবে এটি কেবল একটি ডিইবিজি তৈরির জন্য এটি করে does

আপনি যদি কোডটি পরিবর্তন করেন যাতে ভেরিয়েবলটি একটি পৃথক পদ্ধতিতে সংজ্ঞায়িত করা হয় তবে এটি আপনার প্রত্যাশা অনুযায়ী কাজ করবে।

নিম্নলিখিত কোডের আউটপুট হল:

False
True

এবং কোড:

using System;

namespace ConsoleApp1
{
    class Finalizable
    {
        ~Finalizable()
        {
            _extendMyLifetime = this;
        }

        public static bool LifetimeExtended => _extendMyLifetime != null;

        static Finalizable _extendMyLifetime;
    }

    class Program
    {
        public static void Main()
        {
            test();

            Console.WriteLine(Finalizable.LifetimeExtended); // False.

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

            Console.WriteLine(Finalizable.LifetimeExtended); // True.
        }

        static void test()
        {
            new Finalizable();
        }
    }
}

তাই মূলত আপনার বোঝার সঠিক ছিল, কিন্তু আপনি কি জানতেন না যে গোপন কম্পাইলার আপনার পরিবর্তনশীল টিকিয়ে রাখার জন্য যাচ্ছিলেন পর্যন্ত পর তোমাকে ডেকেছিলাম GC.Collect()- এমনকি আপনি যদি সুস্পষ্টরূপে নাল তা সেট!

আমি উপরে উল্লিখিত হিসাবে, এটি কেবল একটি ডিইবিইউজি বিল্ডের জন্য ঘটে - সম্ভবত পদ্ধতিটির শেষে ডিবাগ করার সময় আপনি স্থানীয় ভেরিয়েবলের মানগুলি পরীক্ষা করতে পারেন (তবে এটি কেবল একটি অনুমান!)!

মূল কোডটি রিলিজ বিল্ডের প্রত্যাশার মতো কাজ করে - সুতরাং false, trueএকটি রিলিজ বিল্ড এবং false, falseএকটি ডিইবিইউজি বিল্ডের জন্য নিম্নলিখিত কোড আউটপুট দেয় :

using System;

namespace ConsoleApp1
{
    class Finalizable
    {
        ~Finalizable()
        {
            _extendMyLifetime = this;
        }

        public static bool LifetimeExtended => _extendMyLifetime != null;

        static Finalizable _extendMyLifetime;
    }

    class Program
    {
        public static void Main()
        {
            new Finalizable();

            Console.WriteLine(Finalizable.LifetimeExtended); // False.

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

            Console.WriteLine(Finalizable.LifetimeExtended); // True iff RELEASE build.
        }
    }
}

সংযোজন হিসাবে: নোট করুন যে আপনি যদি কোনও শ্রেণীর জন্য ফাইনালাইজারে এমন কিছু করেন যা কারণে কোনও কারণটিকে কোনও প্রোগ্রামের মূল থেকে অ্যাক্সেসযোগ্য বলে প্রমাণিত করা হয়, তবে সেই বস্তুটি আর আবর্জনা-সংগ্রহ করা হবে না যতক্ষণ না সেই অবজেক্টটি আর না থাকে রেফারেন্সড।

অন্য কথায়, আপনি চূড়ান্তকরণকারীর মাধ্যমে কোনও বস্তুকে "মৃত্যুর স্থগিতাদেশ" দিতে পারেন। এটি সাধারণত একটি খারাপ ডিজাইন হিসাবে ধরা হয়, যদিও!

উদাহরণস্বরূপ, উপরের কোডটিতে, যেখানে আমরা _extendMyLifetime = thisফাইনালাইজারটি করি সেখানে আমরা বস্তুর জন্য একটি নতুন রেফারেন্স তৈরি করছি, সুতরাং এটি আর আবর্জনা-সংগ্রহ করা হবে না যতক্ষণ না _extendMyLifetime(এবং অন্য কোনও রেফারেন্স) আর এর উল্লেখ না করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.