לדלג לתוכן

מה זה page fault - ולמה השם שלו הרבה יותר מפחיד מהמציאות

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

אז מה זה בעצם page fault

כדי להבין page fault, קודם צריך לזכור שכל תוכנית עובדת עם זיכרון וירטואלי - מרחב כתובות פרטי שמתורגם לכתובות פיזיות ב-RAM על ידי החומרה ומערכת ההפעלה. ה-page fault קורה כשתוכנית מנסה לגשת לעמוד זיכרון (page) וירטואלי, אבל המיפוי לזיכרון הפיזי לא קיים ברגע הזה כמו שהתוכנית ציפתה. במקום לקרוס מיד, המעבד עוצר ומעביר שליטה לקרנל, ואומר לו בעצם - יש כאן בעיה, תטפל בזה.

השם fault נשמע כמו שגיאה, אבל ברוב המקרים זו לא שגיאה בכלל - זו בקשה לעזרה שהקרנל יודע בדיוק איך לטפל בה.

הסוג הקל שקורה כל הזמן בלי שתשימו לב - minor page fault

יש page fault שנקרא minor, מינורי. הוא קורה כשהעמוד שהתוכנית מבקשת בעצם כבר נמצא בזיכרון הפיזי, אבל פשוט עדיין לא מופה לטבלת העמודים של התהליך הספציפי הזה. זה קורה למשל ממש בתחילת הרצה של תוכנית, או כשמשתמשים בקבצים ממופי-זיכרון (memory-mapped files). במקרה כזה, הקרנל פשוט מוסיף את המיפוי החסר לטבלה, וממשיכים הלאה. זה מהיר, זול, וקורה אלפי פעמים בכל שנייה בלי שתרגישו בכלל.

כשבאמת צריך לפנות לדיסק - major page fault

הסוג השני נקרא major, מייג'ורי, וזה כבר יקר יותר. זה קורה כשהנתונים המבוקשים באמת לא נמצאים ב-RAM בכלל, וצריך להביא אותם מהדיסק - למשל זיכרון שהוחלף (swapped out) בגלל לחץ על ה-RAM, או קובץ ממופה-זיכרון שנקרא בפעם הראשונה. כאן הקרנל צריך לבצע פעולת קלט-פלט אמיתית מול הדיסק, שהיא איטית בהרבה מגישה לזיכרון - סדרי גודל של הבדל. זו הסיבה שתוכניות שסובלות מ-swapping כבד מרגישות "תקועות", למרות שמבחינת המעבד שום דבר לא נשבר, פשוט מחכים לדיסק.

אז מתי זה כן שגיאה אמיתית - segmentation fault

עכשיו לחלק המעניין. יש מקרה שבו page fault הוא באמת שגיאה - כשתוכנית מנסה לגשת לזיכרון שהיא בכלל לא אמורה לגעת בו, כמו מצביע null, או גישה מחוץ לתחום שהוקצה לה. גם אז המעבד מזהה page fault ומעביר שליטה לקרנל, בדיוק כמו במקרים הרגילים. אבל הפעם, הקרנל בודק ומגלה שאין לו מה לתקן כאן - הכתובת הזו לא אמורה להיות ממופה בכלל, ולא בטעות. במקרה הזה, הקרנל לא מתקן את המיפוי, אלא שולח לתוכנית אות שאומר לה בעצם - עצרי, אין לך זכות לגעת שם - ובלינוקס זה בדיוק מה שנקרא segmentation fault, שגיאת פילוג.

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

למה ההבחנה הזו חשובה

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

לסיכום

ה-page fault הוא לא שגיאה במובן הרגיל של המילה - זה מנגנון שדרכו מערכת ההפעלה עוזרת לתהליך לגשת לזיכרון שהוא צריך, בין אם זה תיקון מהיר של מיפוי חסר (מינורי) ובין אם זה הבאת נתונים אמיתית מהדיסק (מייג'ורי). רק כשהבקשה עצמה בלתי לגיטימית מלכתחילה, המנגנון הזה הופך לשגיאת פילוג, segmentation fault, שקוטלת את התוכנית. אז בפעם הבאה שתראו את המילה page fault איפשהו בלוגים, אל תיבהלו - סביר להניח שזה בדיוק המחשב שלכם עושה את מה שהוא אמור לעשות.

בואו תמשיכו את הלמידה עם קהילה שכבר שם.

הצטרפו לקהילה בדיסקורד