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

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

- אז מה ההבדל בין האחסון לזכרון?
- אחסון שומר מידע גם אחרי שהמחשב נכבה, האחסון מאוד איטי והוא יכול לשמור הרבה יותר מידע מאשר הזכרון. נשתמש בו כדי לשמור קבצים, ומידע גדול.
- לעומת זאת הזכרון לא שומר מידע אחרי שהמחשב נכבה, הזכרון הוא מאוד מהיר והוא יכול לשמור פחות מידע מאשר האחסון. המעבד משתמש בזכרון כדי לשמור את כל המידע הנחוץ בזמן שהמחשב רץ: הזכרון של התוכנות שרצות (משתנים, אובייקטים, הקוד מכונה, קבצים פתוחים), ועוד.
איסוף זבל¶
- למחשב שלנו יש כמות מוגבלת של זכרון (אין הרבה כמו אחסון), לשם כך אנחנו רוצים שהתוכנה שלנו תשתמש בכמה שפחות זכרון בכל זמן נתון. אחרי שסיימנו להשתמש בקובץ שפתחנו אנחנו צריכים לסגור אותו כדי לחסוך בזכרון.
- היום בשיעור נדבר על מספר דרכים שבהם תוכנות מנהלות זכרון.
ידני¶
- בעבר, תוכנות היו צריכות להקצות זכרון ידנית, ולמחוק אותו. כל פעם שהיינו יוצרים למשל אובייקט, היינו צריכים לזכור למחוק אותו כשאנחנו מסיימים להשתמש בו, בפייתון אנחנו עדיין יכולים להשתמש בשיטה הזו בדרך הבאה:
- בקוד למעלה השתמשנו ב
delכדי למחוק ידנית את האובייקט a מהזכרון של התוכנה שלנו. - כאשר למשל אובייקטים שיצרנו יוצאים מסקופ, גם אותם נרצה למחוק:
- למזלנו בשפת פייתון אובייקטים נמחקים לבד כשהם יוצאים מסקופ, אז אנחנו לא צריכים לזכור לעשות את זה בכל פעם.
אוטמטי¶
- מאוד קשה לשכוח לנקות את הזכרון של כל האובייקטים שאתה משתמש בהם בתוכנה, וגם זה דורש לכתוב הרבה קוד ולשם כך יש מספר שיטות אוטמטיות שבהן שפות תכנות מודרניות כמו פייתון מנקות זכרון בצורה אוטמטית.
- אנחנו נעבור רק על שיטה אחת, והפופלרית ביותר שנקראת garbage collector - איסוף זבל,
- איסוף זבל - garbage collector היא שיטה שבה כל פעם שאובייקט שהוקצה בשבילו זכרון יוצא מסקופ ואף אחד לא משתמש בו, הוא נמחק מהזכרון. יש המון סוגים של אלגוריתמים של garbage collector, זה נושא מאוד גדול ומסובך ואתם מוזמנים לקרוא עליו.
- בקוד למעלה אנחנו מקצים המון פעמים אובייקטים, ובגלל שאף אחד לא משתמש בהם הם נמחקים בכל חזרה של הלולאה.
הבעיה בgarbage collector¶
- הgarbage collector מנקה רק כאשר שום אובייקט בסקופ לא משתמש באובייקט שאותו הוא רוצה לנקות, זה אומר שיכול להיות לנו אובייקט ששכחנו ממנו לגמריי, שמחזיק המון אובייקטים בתוכו, וכל עוד הוא לא יוצא מסקופ האובייקטים שבתוכו לא ימחקו, ראו את הדוגמה למטה:
- הקוד למעלה הוא קוד לגטימי ולקוח מקוד של משחק, הקוד מחפש את כל האוייבים במפה של המשחק ושומר אותם ברשימה שנקראת
game_entities - כל עוד game_entities נמצא בסקופ, כל האובייקטים בתוכו לא ימחקו אף פעם. ולמעשה במקרה הזה
game_entitiesזה משתנה גלובלי, ויכול להיות שנשכח ממנו, וכשזה יקרה יהיה לנו המון אובייקטים שחשבנו שיצאו מסקופ ונמחקו אבל בעצם לא. וזה עלול להעמיס על הזכרון של המשחק, ולשם כך הדבר הזה נקרא "memory leak" - בעצם עלינו לשים לב שכשאנחנו כותבים תוכנות גדולות, שהgarbage collector באמת מוחק כל דבר שאנחנו לא משתמשים בו, ובגלל הדרך שבה הוא עובד - גם אם נשכח למחוק רק רשימה אחת, יכול להיות שהיא מחזירה מאות אובייקטים בחיים.
- עלינו להמנע מכמה שיותר "memory leak"-ים, שימו לב לזה!