שני הסנטים שלי ב- GC.Collect בשיטת C #

שיטת GC.Collect () כבר זמן רב פופולרית בקרב מפתחי .Net. עם זאת, כמעט מעטים מאיתנו לא יודעים איך זה עובד בפועל או אם בכלל יש צורך בשיחה אליו.

ה- CLR (Common Language Runtime) מאמץ את איסוף האשפה כמנגנון לניקוי המשאבים הנצרכים על ידי היישום שלך. שים לב שכשאתה יוצר אובייקטים ב- .Net, הם מאוחסנים בערימה המנוהלת, וכשסיימת להשתמש בהם, אתה לא צריך לדאוג לנקות אותם - זמן הריצה יעשה את זה בשבילך.

ה- CLR מארגן את הערימה המנוהלת לדורות. שלושת הדורות שאליהם מאורגנת הערימה המנוהלת הם: דור 0, דור 1 ודור 2. ה- GC מיומן להחזיר לעצמו את הזיכרון שתופס אובייקטים מנוהלים. עם זאת, עליך לעקוב אחר הנחיות מסוימות כדי להקל על איסוף האשפה כדי לשפר את ביצועי היישום שלך.

האם עלי להשתמש בשיטת GC.Collect ()?

ראשית, האם אתה בכלל צריך להתקשר ל- GC. לאסוף בקוד היישום שלך? התשובה ברוב המקרים היא לא. תן לי עכשיו לספר לך מה השיטה הזו עושה ומדוע כדאי להימנע מקריאה לשיטה זו ברוב המקרים.

כשאתה מתקשר לשיטת GC.Collect (), זמן הריצה מבצע הליכה של מחסנית כדי לקבוע את האובייקטים שניתן להגיע אליהם ואת אלה שאינם. זה גם מקפיא את החוט הראשי (וגם כל שרשור הילד שהוא יצר) של היישום. במילים אחרות, כאשר קוראים לשיטת GC.Collect (), זמן הריצה מבצע איסוף אשפה חוסם של כל הדורות.

תמיד אעדיף לא להשתמש ב- GC.Collect () אלא אם כן יש סיבה ספציפית להשתמש בה. GC מורכב בדרך כלל משלבי הסימון והטאטא ואחריו שלב דחיסה. הזמן שבזמן הריצה לביצוע 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" לדור הבא הבא. הסיבה לכך היא שהאובייקט "אובייקט" שורד מאיסוף האשפה בכל אחד משני המקרים, כלומר, הוא אינו מוחזר באף אחת משתי השיחות שבוצעו לשיטת GC.Collect ().

אתה יכול לכפות איסוף אשפה לכל שלושת הדורות או לדור ספציפי בשיטת GC.Collect (). שיטת GC.Collect () עמוסה יתר על המידה - אתה יכול להתקשר אליה ללא פרמטרים או אפילו על ידי העברת מספר הדור שתרצה לאוסף האשפה לאסוף.

שים לב שאובייקטים שיש בהם מסיימים סופיים (ואם לא בוצעה קריאה ל- SuppressFinalize) לא ייאספו כאשר תתבצע קריאה לשיטת GC.Collect (). במקום זאת, אובייקטים כאלה יוצבו בתור הסיום. אם תרצה לאסוף גם את האובייקטים האלה, תצטרך להתקשר לשיטת GC.WaitForPendingFinalizers () כדי לנקות את האובייקטים האלה כאשר מחזור ה- GC הבא יופעל. בעיקרו של דבר, השבת הזיכרון שנכבש על ידי אובייקטים שמיישמים את הגמר דורשת שני מעברים מאחר וחפצים כאלה ממוקמים בתור הסיום במקום להחזירם במעבר הראשון כאשר אספן האשפה פועל.