Προγραμματισμός

Τα δύο σεντ μου στο GC. Συλλέξτε τη μέθοδο στο C #

Η μέθοδος GC.Collect () υπήρξε εδώ και πολύ καιρό δημοφιλής στους προγραμματιστές .Net. Ωστόσο, σχεδόν λίγοι από εμάς γνωρίζουν πώς λειτουργεί πραγματικά ή, εάν απαιτείται μια κλήση σε αυτό.

Το CLR (Common Language Runtime) υιοθετεί τη συλλογή απορριμμάτων ως μηχανισμό για τον καθαρισμό των πόρων που καταναλώνονται από την εφαρμογή σας. Σημειώστε ότι όταν δημιουργείτε αντικείμενα στο .Net, αποθηκεύονται στον διαχειριζόμενο σωρό και όταν τελειώσετε με τη χρήση τους, δεν χρειάζεται να ανησυχείτε για τον καθαρισμό τους - ο χρόνος εκτέλεσης θα το έκανε για εσάς.

Το CLR οργανώνει τον διαχειριζόμενο σωρό σε γενιές. Οι τρεις γενιές στις οποίες οργανώνεται ο διαχειριζόμενος σωρός είναι: Generation 0, Generation 1 και Generation 2. Το GC είναι ικανό να ανακτήσει τη μνήμη που καταλαμβάνουν τα διαχειριζόμενα αντικείμενα. Ωστόσο, πρέπει να ακολουθήσετε ορισμένες οδηγίες για τη διευκόλυνση της ταχύτερης συλλογής απορριμμάτων, ώστε να βελτιώσετε την απόδοση της εφαρμογής σας.

Πρέπει να χρησιμοποιήσω τη μέθοδο GC.Collect ();

Πρώτα απ 'όλα, πρέπει καθόλου να καλέσετε το GC. Συλλέξτε τον κωδικό της εφαρμογής σας; Η απάντηση στις περισσότερες περιπτώσεις είναι όχι. Επιτρέψτε μου τώρα να σας πω τι κάνει αυτή η μέθοδος και γιατί πρέπει να αποφύγετε να καλέσετε αυτήν τη μέθοδο στις περισσότερες περιπτώσεις.

Όταν πραγματοποιείτε μια κλήση στη μέθοδο GC.Collect (), ο χρόνος εκτέλεσης εκτελεί μια βόλτα στοίβας για να προσδιορίσει τα αντικείμενα που είναι προσβάσιμα και εκείνα που δεν είναι. Επίσης παγώνει το κύριο νήμα (και επίσης τυχόν παιδικά νήματα που δημιούργησε) της εφαρμογής. Με άλλα λόγια, όταν καλείται η μέθοδος GC.Collect (), ο χρόνος εκτέλεσης εκτελεί μια συλλογή απορριμμάτων απορριμμάτων όλων των γενεών.

Θα προτιμούσα πάντα να μην χρησιμοποιώ το GC.Collect () εκτός εάν υπάρχει συγκεκριμένος λόγος για να το χρησιμοποιήσω. Ένα GC αποτελείται συνήθως από τις φάσεις Mark και Sweep που ακολουθούνται από μια φάση συμπύκνωσης. Ο χρόνος που αφιερώνεται στο χρόνο εκτέλεσης για την εκτέλεση ενός GC μπορεί να γίνει εμπόδιο, οπότε, χρησιμοποιήστε το πολύ σπάνια και αν χρειαστεί πραγματικά. Ο Rico Mariani δηλώνει: "Εξετάστε το ενδεχόμενο να καλέσετε το GC.Collect () εάν κάποιο συμβάν που δεν επαναλήφθηκε μόλις συνέβη και αυτό το συμβάν είναι πολύ πιθανό να έχει προκαλέσει θάνατο πολλών παλαιών αντικειμένων."

Χρησιμοποιώντας τη μέθοδο GC.Collect ()

Δείτε πώς μπορείτε να καλέσετε τη μέθοδο GC.Collect () στον κώδικά σας.

GC.Collect ();

Σημειώστε ότι μπορείτε επίσης να συλλέξετε αντικείμενα που σχετίζονται με μια συγκεκριμένη γενιά.

GC. Συλλογή () - χρησιμοποιείται για τη συλλογή αντικειμένων που υπάρχουν στις γενιές 0, 1, 2

GC.Collect (0) - χρησιμοποιείται για τη συλλογή αντικειμένων που υπάρχουν στη γενιά 0

GC.Collect (1) - χρησιμοποιείται για τη συλλογή αντικειμένων που υπάρχουν στις γενιές 0 και

Μπορείτε επίσης να προσδιορίσετε πόση μνήμη έχει απελευθερωθεί κάνοντας μια κλήση στη μέθοδο GC.Collect (). Για να το κάνετε αυτό, μπορείτε να επωφεληθείτε από τη μέθοδο System.GC.GetTotalMemory () όπως φαίνεται στο απόσπασμα κώδικα παρακάτω.

// Γράψτε κώδικα για να δημιουργήσετε μερικά μεγάλα αντικείμενα εδώ

Console.WriteLine ("Συνολική διαθέσιμη μνήμη πριν από τη συλλογή: {0: N0}", System.GC.GetTotalMemory (false));

System.GC.Collect ();

Console.WriteLine ("Συνολική διαθέσιμη συλλογή μνήμης: {0: N0}", System.GC.GetTotalMemory (true));

Η μέθοδος GC.GetGeneration () μπορεί να χρησιμοποιηθεί για να γνωρίζει τη γενιά στην οποία ανήκει ένα αντικείμενο. Ανατρέξτε στην παρακάτω λίστα κωδικών.

static void Main (συμβολοσειρά [] args)

       {

Λίστα obj = νέα λίστα () {"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));

Κονσόλα. Διαβάστε ();

       }

Όταν εκτελείτε το παραπάνω πρόγραμμα, δείτε τι εκτυπώνεται στο παράθυρο της κονσόλας.

0

1

2

Όπως μπορείτε να δείτε, κάθε κλήση στη μέθοδο GC.Collect () προωθεί το αντικείμενο "obj" στην επόμενη ανώτερη γενιά. Αυτό συμβαίνει επειδή το αντικείμενο "obj" επιβιώνει από τη συλλογή απορριμμάτων σε καθεμία από τις δύο περιπτώσεις, δηλαδή δεν διεκδικείται εκ νέου σε καμία από τις δύο κλήσεις που πραγματοποιούνται στη μέθοδο GC.Collect ().

Μπορείτε να επιβάλλετε τη συλλογή απορριμμάτων είτε στις τρεις γενιές είτε σε μια συγκεκριμένη γενιά χρησιμοποιώντας τη μέθοδο GC.Collect (). Η μέθοδος GC.Collect () είναι υπερφορτωμένη - μπορείτε να την καλέσετε χωρίς παραμέτρους ή ακόμη και μεταβιβάζοντας τον αριθμό παραγωγής που θέλετε να συλλέξει ο συλλέκτης απορριμμάτων.

Λάβετε υπόψη ότι τα αντικείμενα που έχουν οριστικοποιητές (και εάν δεν έχει πραγματοποιηθεί μια κλήση στη μέθοδο SuppressFinalize) δεν θα συλλέγονταν όταν πραγματοποιείται μια κλήση στη μέθοδο GC.Collect (). Αντίθετα, τέτοια αντικείμενα θα τοποθετηθούν στην ουρά οριστικοποίησης. Εάν θέλετε να συλλέξετε και αυτά τα αντικείμενα, θα χρειαστεί να πραγματοποιήσετε μια κλήση στη μέθοδο GC.WaitForPendingFinalizers (), ώστε αυτά τα αντικείμενα να καθαριστούν κατά την εκτέλεση του επόμενου κύκλου GC. Στην ουσία, η ανάκτηση της μνήμης που καταλαμβάνεται από αντικείμενα τα οποία έχουν υλοποιήσει οριστικοποιητές απαιτεί δύο περάσματα, καθώς τέτοια αντικείμενα τοποθετούνται στην ουρά οριστικοποίησης και όχι ανάκτηση στο πρώτο πέρασμα όταν εκτελείται ο συλλέκτης απορριμμάτων.