איסוף אשפה ב פִּיתוֹן הוא תהליך אוטומטי המטפל בהקצאת זיכרון והקצאת זיכרון המבטיח שימוש יעיל בזיכרון. בניגוד לשפות כגון ג אוֹ C++ שבו המתכנת חייב להקצות ולהקצות זיכרון באופן ידני Python מנהלת את הזיכרון באופן אוטומטי באמצעות שתי אסטרטגיות עיקריות:
- ספירת הפניות
- איסוף אשפה
ספירת הפניות
Python משתמש ספירת הפניות לניהול זיכרון. כל אובייקט עוקב אחר כמה הפניות מצביעות עליו. כאשר ספירת הפניות יורדת לאפס, כלומר לא נשארות הפניות Python מבטל את הקצאת האובייקט באופן אוטומטי. דוּגמָה:
Pythonimport sys x = [1 2 3] print(sys.getrefcount(x)) y = x print(sys.getrefcount(x)) y = None print(sys.getrefcount(x))
תְפוּקָה
2 3 2
הֶסבֵּר:
- x מופנה פעמיים בהתחלה (פעם אחת על ידי x פעם אחת על ידי getrefcount()).
- מקצה y = x מגדיל את הספירה.
- סְבִיבָה y = אין מסיר הפניה אחת.
בעיה בספירת הפניות
ספירת הפניות נכשלת בנוכחות הפניות מחזוריות, כלומר אובייקטים שמתייחסים זה לזה במחזור. גם אם שום דבר אחר לא מצביע עליהם ספירת ההתייחסות שלהם לעולם לא מגיעה לאפס. דוּגמָה:
Pythonimport sys x = [1 2 3] y = [4 5 6] x.append(y) y.append(x) print(sys.getrefcount(x)) print(sys.getrefcount(y))
תְפוּקָה
3 3
הֶסבֵּר:
- x מכיל ו ו ו מכיל x .
- גם לאחר המחיקה x ו ו Python לא יוכל לשחרר את הזיכרון רק באמצעות ספירת הפניות מכיוון שכל אחד עדיין מפנה לשני.
איסוף אשפה עבור הפניות מחזוריות
איסוף אשפה היא טכניקת ניהול זיכרון המשמשת בשפות תכנות כדי להחזיר אוטומטית זיכרון שאינו נגיש עוד או בשימוש על ידי היישום. כדי לטפל בהפניות מעגליות כאלה Python משתמש ב-a אספן אשפה (GC) ממודול gc המובנה. אספן זה מסוגל לזהות ולנקות אובייקטים המעורבים במחזורי התייחסות.
איסוף אשפה דורי
אוסף האשפה הדור של Python נועד להתמודד עם הפניות מחזוריות. הוא מארגן חפצים לשלושה דורות על סמך תוחלת החיים שלהם:
- דור 0: אובייקטים חדשים שנוצרו.
- דור 1: חפצים ששרדו מחזור איסוף אחד.
- דור 2: חפצים ארוכים.
כאשר מתרחשים מחזורי התייחסות, אספן האשפה מזהה ומנקה אותם באופן אוטומטי ומשחרר את הזיכרון.
איסוף אשפה אוטומטי של מחזורים
איסוף האשפה פועל באופן אוטומטי כאשר מספר ההקצאות חורג ממספר ההקצאות ברף מסוים. ניתן לבדוק את הסף הזה באמצעות מודול gc.
Pythonimport gc print(gc.get_threshold())
תְפוּקָה
(2000 10 10)
הֶסבֵּר: הוא מחזיר את tuple הסף לדורות 0 1 ו-2. כאשר ההקצאות חורגות, מופעלת איסוף הסף.
איסוף אשפה ידני
לפעמים זה מועיל להפעיל ידנית את אוסף האשפה, במיוחד במקרה של מחזורי התייחסות. דוּגמָה:
Pythonimport gc # Create a cycle def fun(i): x = {} x[i + 1] = x return x # Trigger garbage collection c = gc.collect() print(c) for i in range(10): fun(i) c = gc.collect() print(c)
תְפוּקָה
0 10
הֶסבֵּר:
- בהחלט כיף (i) יוצר הפניה מחזורית על ידי הפניה למילון עצמו.
- gc.collect() מפעיל איסוף אשפה ומאחסן את ספירת החפצים שנאספו (בהתחלה 0).
- עבור i in range(10) שיחות כיף (i) 10 פעמים יצירת 10 הפניות מחזוריות.
- gc.collect() מפעיל שוב איסוף אשפה ומדפיס את ספירת המחזורים שנאספו.
סוגי איסוף אשפה ידני
- איסוף אשפה מבוסס זמן: אספן האשפה מופעל במרווחי זמן קבועים.
- איסוף אשפה מבוסס אירועים: אספן האשפה נקרא בתגובה לאירועים ספציפיים כגון כאשר משתמש יוצא מהאפליקציה או כאשר האפליקציה הופכת ללא שימוש.
איסוף אשפה בכפייה
אספן האשפה (GC) של Python פועל אוטומטית כדי לנקות חפצים שאינם בשימוש. כדי לאלץ אותו ידנית השתמש ב-gc.collect() מהמודול gc. דוּגמָה:
Pythonimport gc a = [1 2 3] b = {'a': 1 'b': 2} c = 'Hello world!' del abc gc.collect()
הֶסבֵּר:
- מה-a b c מוחק הפניות ל א ב ו ג מה שהופך אותם לזכאים לאיסוף אשפה.
- gc.collect() מאלץ איסוף אשפה לשחרר זיכרון על ידי ניקוי אובייקטים ללא הפניה.
השבתת איסוף האשפה
ב-Python אוסף האשפה פועל אוטומטית כדי לנקות אובייקטים שאין להם התייחסות. כדי למנוע ממנו לפעול אתה יכול להשבית אותו באמצעות gc.disable() מהמודול gc. דוּגמָה:
Pythonimport gc gc.disable() gc.enable()
הֶסבֵּר:
- gc.disable() משבית את איסוף האשפה האוטומטי.
- gc.enable() מאפשר מחדש איסוף אשפה אוטומטי.
אינטראקציה עם אספן אשפה פיתון
מנגנון מובנה בשם Python garbage collector מבטל אוטומטית אובייקטים שכבר אין להם התייחסות על מנת לפנות זיכרון ולעצור דליפות זיכרון. מודול Python gc מציע מספר דרכים ליצירת אינטראקציה עם אספן האשפה אשר לרוב מבוצע באופן אוטומטי.
1. הפעלה והשבתה של אוסף האשפה: אתה יכול להפעיל או להשבית את אוסף האשפה באמצעות gc. לְאַפשֵׁר() ו gc. disable() פונקציות בהתאמה. דוּגמָה :
כפתור מרכזי ב-CSSPython
import gc # Disable gc.disable() # Enable gc.enable()
2. אילוץ איסוף אשפה: אתה יכול להפעיל ידנית איסוף אשפה באמצעות gc. לֶאֱסוֹף() פוּנקצִיָה. זה יכול להיות שימושי במקרים שבהם אתה רוצה לכפות איסוף אשפה מיידי במקום לחכות לאיסוף אשפה אוטומטי. דוּגמָה:
Pythonimport gc gc.collect()
3. בדיקת הגדרות אספן האשפה: אתה יכול לבדוק את ההגדרות הנוכחיות של אוסף האשפה באמצעות gc.get_threshold() פונקציה שמחזירה tuple המייצג את הספים הנוכחיים לדורות 0 1 ו-2. דוּגמָה:
Pythonimport gc t = gc.get_threshold() print(t)
תְפוּקָה
(2000 10 10)
4. הגדרת ספי אספן אשפה: אתה יכול להגדיר את הספים לאיסוף אשפה באמצעות gc.set_threshold() פוּנקצִיָה. זה מאפשר לך להתאים באופן ידני את הספים עבור דורות שונים אשר יכול להשפיע על תדירות איסוף האשפה. דוּגמָה:
Pythonimport gc gc.set_threshold(500 5 5) t = gc.get_threshold() print(t)
תְפוּקָה
(500 5 5)
יתרונות וחסרונות
בואו נחקור כמה מהיתרונות והחסרונות של אוסף האשפה של Python.
יתרונות | חסרונות |
|---|---|
ניהול זיכרון אוטומטי | עשוי להציג תקורה של ביצועים |
אין טיפול ידני בזיכרון | דורש הבנה של מושגי זיכרון |
ניקוי יעיל דרך דורות | שליטה מוגבלת בתזמון של GC |
הגדרות GC הניתנות להתאמה אישית | אפשרות של באגים או דליפות זיכרון |