דליפת זיכרון
דליפת זיכרון היא מצב שבו תוכנה לא משחררת זיכרון שהקצתה באופן דינמי, למרות שכבר אין לה צורך בו. חלק מהזיכרון הפנוי נותר תפוס ולא ניתן להשתמש בו במשך זמן ריצת התוכנה, מה שעלול לפגום בביצועי המערכת, בפרט אם מדובר בתוכנה שמתוכננת לרוץ פרק זמן ממושך ברצף. דליפת זיכרון היא המצב השכיח ביותר של דליפה במשאבי מערכת.
שגיאות תכנות המוליכות לדליפת זיכרון הן נפוצות למדי בשפות תכנות אשר אין להם "איסוף זבל" מובנה אוטומטי ואשר מסתמכות בצורה נרחבת על פעולות עם מצביעים. עם שפות אלו נמנות C ו++C.
ניתן להבדיל בין שני מצבים בסיסיים של דליפת זיכרון: כל עוד קיימת דרך להורות למערכת ההפעלה לשחרר את הזיכרון, זוהי דליפה מינורית שכן היא חסומה בגודלה. אולם כאשר לא ניתן לבצע יותר שחרור של הזיכרון שהוקצה - למשל איפוס של מצביע יחיד שהצביע אל אזור הזיכרון - זוהי דליפה חמורה, שעלולה לגרום נזק גדל והולך בכל ביצוע חוזר של הקוד שיוצר את הדליפה.
דליפת זיכרון עלולה לבוא גם בעטיו של זיכרון שאינו בשימוש התוכנה הספציפית, שכן לא התוכנית עצמה, אלא רכיב של מערכת ההפעלה אחראי לניהול הזיכרונות. כאשר חלק גדול מדי מהזיכרון נותר תפוס ואינו משוחרר עלולים המערכת כולה או לכל הפחות, חלקים חשובים בה, להפסיק לתפקד כראוי. מערכות ההפעלה המודרניות יודעות לשחרר את כל הזיכרון שתופסת תוכנית בזמן היציאה מהתוכנית. באופן זה, מערכת ההפעלה לא נכנסת לבעיה עקב הדליפה, וממשיכה להתנהג כרגיל. כמו כן, ניהול של זיכרון וירטואלי מאפשר לבודד את ההשלכות של הקצאה מיותרת בין תהליכים ובכך למזער את ההשלכות הנובעות מדליפה שכזו, אם כי לא למנוע אותן לחלוטין.
בשפות אשר מספקות ניהול זיכרון אוטומטי (איסוף זבל), כמו #C, Java Lisp, פייתון או Perl, לא ייתכנו מצבים של דליפות זיכרון. דבר זה נוח בהרבה למפתחים, אולם הוא פחות גמיש ובעייתי בשל תקורת הביצועים שנוצרת.
דוגמה פשוטה בשפת C[עריכה]
להלן תוכנית קצרה אשר יוצרת דליפת זיכרון:
הערות:
- (1) המידע על כתובת הזיכרון שאליה התייחס המשתנה string1 בתחילה אובד, שכן ערך אחר, כלומר כתובת של אזור אחר בזיכרון, מוכנס למשתנה. (שורה 9)
- (2) שחרור הזיכרון הנ"ל יתבצע כהלכה. (שורה 10)
- (3) שגיאה! הזיכרון כבר שוחרר שורה קודם לכן. (שורה 11)
| שורה | קוד |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *string1 = malloc(sizeof(char)*51);
char *string2 = malloc(sizeof(char)*51);
if( (string1!=NULL) && (string2!=NULL) )
{
fgets(string2,51,stdin);
string1 = string2; // (1)
free(string2); // (2)
free(string1); // (3)
return 0;
}
else
return 1;
}
|
כלים לאיתור דליפת זיכרון[עריכה]
קיימים כלים שונים כגון Purify, Valgrind ו-Insure++ אשר מאפשרים זיהוי דליפות זיכרון בתוכניות C ו++C. יש לציין שניתן לממש יכולת "איסוף זבל" סבירה לתוכניות אלו, אך היא אינה מוחלטת. שיטת העבודה של הזיהוי מתבססת על הרעיון, שכל הקצאה של זיכרון, מתבצעת דרך מודול של הכלי ולא באופן ישיר. כל הפרטים הטכניים על ההקצאה נרשמים. עם סיום ריצת התוכנית, הכלי בודק לאלו הקצאות לא בוצע שחרור, והמפתח יכול לקבל דו"ח מלא עם הפניה לקוד המקור, ובעזרתו לפתור את הבעיה.