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

היופי של GC הוא שהוא משחרר זיכרון בשמך, מבלי שתצטרך לעשות דבר. לכן, אתה עשוי להחשיב את זה כמאפיין כה חיוני שאתה מצפה שלכל שפת תכנות תהיה את זה. למרבה הצער, זה לא המקרה; אפילו שפה פופולרית כמו C יכולה להיעדר GC.

כיצד פועלת הקצאת זיכרון?

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

בתכנות, משתנה מייצג מיקום זיכרון. לכן, כאשר אתה מכריז על משתנה חדש, שפת התכנות מקצה מקום בזיכרון עבור המשתנה הזה. למשתנה תהיה כעת כתובת זיכרון. עד שתקצה ערך למשתנה זה, הוא יישאר לא מאותחל, והוא עשוי להכיל ערך זבל כלשהו.

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

instagram viewer

כיצד פועלת חלוקת זיכרון?

הקצאת זיכרון היא תהליך דומה עבור כל שפות התכנות. אבל השיטה המקבילה של הקצאת זיכרון נוטה להיות שונה. ישנם שני סוגים של שיטות חלוקת זיכרון; ידני ואוטומטי. GC מבצע ביטול הקצאה אוטומטי.

חלוקת זיכרון ללא אספן אשפה

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

הספרייה הסטנדרטית (stdlib.h) מכילה את הפונקציות בהן משתמש C לניהול הקצאת זיכרון דינמית. פונקציות אלו כוללות:

  • malloc(): מקצה גודל ספציפי של זיכרון ומחזיר מצביע לאותו זיכרון. אם אין מספיק זיכרון זמין במאגר הזיכרון של מערכת ההפעלה, הוא מחזיר null.
  • free(): מקצה גוש ספציפי של זיכרון ומחזיר אותו למאגר הזיכרון של מערכת ההפעלה.

דוגמה לתוכנית C

#לִכלוֹל
#לִכלוֹל

intרָאשִׁי()
{
int *ptr; // הכריז על מצביע
int י; // הכריז נגד

// הקצו מקום ל-200 מספרים שלמים
ptr = (int *) malloc(200 * מידה של(int));

// הכנס ערכי מספר שלמים לזיכרון שהוקצה
// והדפיס כל ערך לקונסולה
ל (j = 0; j < 200; j++)
{
ptr[j] = j;
printf("%d\t",ptr[j]);
}

// הקצה את הזיכרון שהוקצה קודם לכן
חינם(ptr);
לַחֲזוֹר0;
}

הקוד שלמעלה מקצה זיכרון לאחסון 200 ערכי מספרים שלמים באמצעות ה malloc() פוּנקצִיָה. הוא משתמש במצביע כדי לגשת למיקום הזיכרון הזה ומאחסן בו 200 ערכי מספרים שלמים. המצביע גם מדפיס את הנתונים המאוחסנים במיקום הזיכרון לקונסולה. לבסוף, התוכנית מקצה את הזיכרון שהוקצה קודם לכן באמצעות חינם() פוּנקצִיָה.

חלוקת זיכרון עם אספן אשפה

מספר שפות תכנות פופולריות משתמשות ב-GC לניהול זיכרון. זה הופך את החיים של מתכנתים שמשתמשים בשפות אלו להרבה יותר קלים. C# ו-Java הן שתי שפות תכנות המשתמשות ב-GC.

ה-C# GC

בתוך ה שפת תכנות C#, GC מנהל את ההקצאה וההקצאה של כתובות זיכרון. לכן, מתכנת C# לא צריך לדאוג לגבי ביטול הקצאת אובייקט לאחר השלמת מטרתו.

ה-C# GC מאתחל מאגר זיכרון, הנקרא הערימה המנוהלת, עבור כל תהליך (או תוכנית) חדש. זה קורא ל VirtualAlloc() פונקציה להקצאת זיכרון ו- VirtualFree() פונקציה כדי להקצות אותו. החלק הטוב ביותר הוא שכל זה קורה ברקע ללא מאמץ ממך, המתכנת.

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

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

ה-Java GC

ב-Java, GC מנהל גם את ההקצאה וההקצאה של כתובות זיכרון. עם זאת, ל- Java יש כיום ארבעה סוגים שונים של אוספי אשפה נתמכים:

  • זבל-ראשון (G1)
  • סידורי
  • מַקְבִּיל
  • אספן זבל (ZGC)

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

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

אספן האשפה G1 מבצע אז את רוב חלוקת הזיכרון שלו בדור הצעיר, ומדי פעם יוצא למדור הדור הישן.

מהם היתרונות של אוסף אשפה?

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

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

איסוף אשפה מפחית שגיאות הקשורות לניהול זיכרון כגון דליפות ושגיאות מצביעים. הסיבה לכך היא שהתהליך אינו תלוי יותר במתכנת וביכולת שלו לכתוב קוד מדויק.