לדלג לתוכן

פתרון מרחב כתובות והתחייבות לזיכרון

ה־AllocationBase נשאר בסיס ההזמנה המקורית בזמן שדפים פנימיים עוברים בין reserved ל־committed. ה־RegionSize יכול להשתנות כי VirtualQuery מקבצת אזורים לפי מאפיינים, ולא לפי אובייקט ההקצאה שהיישום מדמיין.

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

if (!VirtualAlloc(selected, page_size, MEM_COMMIT, PAGE_READWRITE)) {
    VirtualFree(base, 0, MEM_RELEASE);
    return 5;
}
const auto value = *static_cast<volatile unsigned char*>(selected);
std::printf("after recommit=%u\n", static_cast<unsigned>(value));

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

ממשק מעטפת יכול לקבל offset ו־length ולבדוק תחילה offset <= reserved_size, ואז length <= reserved_size - offset. רק אחרי הבדיקות מחשבים כתובת. בנוסף צריך להגדיר אם הממשק דורש יישור מראש או מעגל טווחים בעצמו ומדווח על ההיקף האמיתי.

ה־destructor משתמש בבסיס המקורי עם MEM_RELEASE וגודל אפס. פעולת decommit אינה מאפסת את הבסיס בבעלים, מפני שההזמנה עדיין קיימת. זהו אינווריאנט שונה מעטיפה שמחזיקה הקצאה אחת מסוג malloc.

כשל של רצף כתובות יכול להתרחש בלי שמחסור ב־RAM הוא הסיבה. כשל commit קשור לחשבונאות הגיבוי. כשל גישה מסוג access violation יכול לנבוע מדף לא מחויב או מהגנה שאינה מאפשרת את הפעולה, גם אם יש הרבה זיכרון פנוי.

מדידת RAM צריכה להבחין בין residency, שיתוף ופרטיות. הערך MEM_COMMIT מתאר מצב במפת התהליך, ולא את כל המידע הפיזי הדרוש לחישוב המדד.