Моите два цента на GC. Събира метод в C #

Методът GC.Collect () отдавна е популярен сред разработчиците на .Net. Едва ли малко от нас обаче знаят как работи всъщност или, ако изобщо е необходимо повикване към него.

CLR (Common Language Runtime) приема събирането на боклука като механизъм за почистване на ресурсите, консумирани от вашето приложение. Имайте предвид, че когато създавате обекти в .Net, те се съхраняват в управляваната купчина и когато приключите с използването им, не е нужно да се притеснявате да ги почистите - времето за изпълнение ще го направи вместо вас.

CLR организира управляваната купчина в поколения. Трите поколения, в които се организира управляваната купчина, са: Поколение 0, Поколение 1 и Поколение 2. GC е вещ в възстановяването на паметта, заета от управлявани обекти. Трябва обаче да следвате определени насоки, за да улесните по-бързото събиране на боклука, за да подобрите ефективността на приложението си.

Трябва ли да използвам метода GC.Collect ()?

Първо, изобщо трябва ли да се обадите на GC.Collect в кода на вашето приложение? Отговорът в повечето случаи е отрицателен. Нека сега ви кажа какво прави този метод и защо в повечето случаи трябва да се въздържате от извикване на този метод.

Когато се обадите на метода GC.Collect (), времето за изпълнение изпълнява стека, за да определи обектите, които са достъпни и тези, които не са. Той също така замразява основната нишка (както и всички дъщерни нишки, които е създал) на приложението. С други думи, когато се извика методът GC.Collect (), времето за изпълнение изпълнява блокиращо събиране на боклук от всички поколения.

Винаги бих предпочел да не използвам GC.Collect (), освен ако няма конкретна причина да го използвам. GC обикновено се състои от фазите Mark и Sweep, последвани от фаза на уплътняване. Времето, прекарано по време на изпълнението за изпълнение на GC, може да се превърне в пречка, така че, използвайте го много рядко и ако наистина имате нужда. Рико Мариани заявява: „Помислете за извикване на GC.Collect (), ако току-що се е случило някакво неповтарящо се събитие и е много вероятно това събитие да е причинило смъртта на много стари обекти.“

Използвайки метода GC.Collect ()

Ето как можете да извикате метода GC.Collect () във вашия код.

GC.Collect();

Имайте предвид, че можете също да събирате обекти, които се отнасят до конкретно поколение.

GC.Collect() - използва се за събиране на предмети, присъстващи в поколенията 0, 1, 2

GC.Collect(0) - използва се за събиране на обекти, присъстващи в поколение 0

GC.Collect(1) - използва се за събиране на предмети от поколения 0 и

Можете също така да определите колко памет е освободена, като извикате метода GC.Collect (). За да направите това, можете да се възползвате от метода System.GC.GetTotalMemory (), както е показано в кодовия фрагмент по-долу.

//Write code to create some large objects here

Console.WriteLine("Total available memory before collection: {0:N0}", System.GC.GetTotalMemory(false));

System.GC.Collect();

Console.WriteLine("Total available memory collection: {0:N0}", System.GC.GetTotalMemory(true));

Методът GC.GetGeneration () може да се използва, за да се знае поколението, към което принадлежи обектът. Вижте списъка с кодове, даден по-долу.

static void Main(string[] args)

       {

           List obj = new List() { "Joydip", "Steve" };

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           System.GC.Collect();

           Console.WriteLine(System.GC.GetGeneration(obj));

           Console.Read();

       }

Когато изпълнявате горната програма, ето какво се отпечатва в прозореца на конзолата.

0

1

2

Както можете да видите, всяко извикване на метода GC.Collect () повишава обекта "obj" до следващото по-високо поколение. Това е така, защото обектът "obj" преживява събирането на боклука във всеки от двата случая, т.е. не се възстановява в нито едно от двете извиквания, направени към метода GC.Collect ().

Можете да принудите събирането на боклука или към трите поколения, или към конкретно поколение, използвайки метода GC.Collect (). Методът GC.Collect () е претоварен - можете да го извикате без никакви параметри или дори като предадете генериращия номер, който искате да съберете на събирача на боклука.

Обърнете внимание, че обектите, които имат финализатори (и ако не е осъществено извикване на метода SuppressFinalize), няма да бъдат събрани, когато се направи извикване на метода GC.Collect (). По-скоро такива обекти ще бъдат поставени в опашката за финализиране. Ако искате да съберете и тези обекти, ще трябва да се обадите на метода GC.WaitForPendingFinalizers (), така че тези обекти да бъдат почистени, когато стартира следващият GC цикъл. По същество, възстановяването на паметта, заета от обекти, които имат реализирани финализатори, изисква два прохода, тъй като такива обекти се поставят в опашката за финализиране, вместо да бъдат възстановени при първото преминаване, когато се изпълнява събирачът на боклук.