ניהול זכרון בסביבת .NET
חשוב להבדיל בין שני חלקים של האובייקט, ה Reference והמופע בזכרון. Reference הוא בעצם מין פוינטר מתוחכם שתופס מעט מעוד מקום, ממש זניח, ה GC לא מטפל בו עד שה APPDOMAIN מסיים את עבודתו. Reference מסויים יכל להצביע כל פעם על אובייקט אחר בזכרון, לדוגמה:
string s; s = "pagis"; s = s+"2"; s = "Ayelt Zorer + Pagis = Big Love"; s = null;
אז מה היה לנו? קודם כל הכרזנו על Reference חדש ובהכרזה הזו בעצם אמרנו שהמשתנה s נועד להצביע על חתיכת זכרון שתייצג טיפוס string. כרגע כל מה שיש לנו זה Reference, עוד לא הקצנו זכרון. שורה מתחת לזה אנחנו מבקשים להציב ערך מסוג string שה Reference שלנו, s, יצביע אליו. כעת סביבת ה .NET תדאג להקצאות הזכרון הדרושות ו s מצביע אל אובייקט בזכרון. בשורה הבאה אנחנו מבקשים שהאובייקט שאליו s מצביע ישתנה, שיכיל את מה שהוא מכיל + עוד איזה תו. מכיוון ש string הוא בעצם מערך של char-ים, ומכיוון שהגודל של מערך לא משתנה מרגע שהוכרז, מה שקורה כאן הוא בעצם שנוצר אובייקט חדש בזכרון, שיכיל את ה string החדש ו s יצביע אליו מעכשיו. כרגע יש לנו בזכרון שני אובייקטים שלאחד מהם שום דבר לא מצביע כבר ולכן גם שום דבר לא יבציע אליו בעתיד ולכן הוא מין רוח רפאים. אחר כך אנחנו יוצרים עוד אובייקט מסוג string, שוב ה Reference יצביע על האובייקט החדש ונקבל שתי רוחות רפאים ואובייקט שמשהו כן מצביע אליו, סה"כ 3 אובייקטים תופסים לנו מקום בזכרון, למרות שאנחנו מסוגלים לעשות שימוש רק באחד מהם. בשלב הבא אנחנו מציבים ערך null ב s מה שאומר שכעת ה Reference ששמו s לא מצביע לשום דבר בזכרון, הוא ריק, הוא רק פוינטר אבל שלא מצביע לשום מקום, אפשר להציב בתוכו ערך מה שיגרום לסביבה ליצור מופע חדש בזכרון ולכוון את s להצביע על המופע החדש הזה, אבל בכל מקרה כרגע יש לנו Reference אחד שלא מצביע לכלום או מצביע למופע חדש + 3 אובייקטים בזכרון, מטיפוס string, שתופסים זכרון אבל אין לנו שום יכולת לעשות בהם שימוש, 3 רוחות רפאים. אוקי, עד כאן הקדמה, עכשיו, כשה GC רץ הוא מחפש את כל "רוחות הרפאים" הוא בעצם עובר על כל האובייקטים בזכרון ובודק לאיזה מהם אין שום Reference שמפנה אליו, את האובייקטים האלו הוא ישחרר. לכן, כשאתה מציב Null אתה בעצם כן מאפשר ל GC לפנות את הזכרון (למרות שרצוי לתכנן אפליקציה ככה שתזדקק לכמה שפחות ריצות של ה GC, כי הוא כבד נורא). בכל מקרה, חשוב להדגיש שאם לאובייקט מסויים יש פונקציית Dispose חשוב להשתמש בה, הסיבה שיש הרבה אובייקטים שעושים שימוש בקוד לא מנוהל (unsafe) מה שאומר שה GC לא ינהל להם את הקצאות הזכרון, מה שאומר שאתה בעצם אחראי לשחרר את הזכרון שלהם, מי שכתב את האובייקט דאג לכל הפעולות הדרושות, אתה רק צריך לקרוא ל Dispose כדי לסמן לאובייקט שאתה מסיים להשתמש בו.