Process memory guardian daemon

ב-Android 17 ואילך יש תמיכה בשד PMGD (process memory guardian daemon), שמגן על תקינות המערכת ועל חוויית המשתמש על ידי ניהול פרואקטיבי של השימוש בזיכרון על בסיס כל תהליך. הדמון משפר את היציבות הכוללת של המכשיר על ידי אכיפה הדרגתית של מגבלות זיכרון בתהליכי יעד ספציפיים, ומוודא שדליפות זיכרון או עליות חדות בשימוש בזיכרון לא יגרמו לירידה בביצועים ברמת המערכת.

בעוד שרוצחי זיכרון גלובליים רגילים פועלים רק כשהמערכת כולה נמצאת תחת לחץ, PMGD נוקט גישה גרנולרית. הדמון מבצע את זה על ידי מעקב אחרי ערכי הזיכרון של קבוצת הבקרה v2 עבור תהליכי היעד שלו. כשתהליך ממוקד חורג ממגבלות הזיכרון שהוגדרו לו, pmgd מטפל בהפרות של מגבלות על ידי רישום של אטומי זיכרון של Statsd לפני סיום התהליך.

איך זה עובד

הדמון משתמש ב-inotify כדי להאזין לאירועים של עומס על הזיכרון (במיוחד פעילות של שימוש בזיכרון גבוה באמצעות memory.events). כשמתרחש אירוע זיכרון בתהליך שבמעקב, pmgd מבצע את הפעולות הבאות:

  1. בדיקת זיכרון אנונימית: מעריכה את הזיכרון האנונימי של התהליך. אם הוא חורג מהערך המוגדר של anon_limit_in_mb, ‏ pmgd מפסיק את התהליך באופן מיידי.
  2. תקופת המתנה להחזרת זיכרון: אם הזיכרון האנונימי נמוך ממגבלת הזיכרון האנונימי שצוינה, pmgd ממתין לתקופת חסד להחזרת זיכרון על ידי המערכת (reclaim_wait_time_secs).
  3. הערכת הזיכרון אחרי השחרור: אם הערך של memory.current בתהליך היעד נשאר גדול מ-memory.high או שווה לו אחרי תקופת החסד, או אם הזיכרון האנונימי חורג מ-anon_limit_in_mb,‏ pmgd משבית את התהליך באופן מיידי.

הפעולה הזו מתבצעת באופן רציף עד שהתהליך מופסק או עד שהתהליך משחרר זיכרון ומקטין את השימוש בזיכרון מתחת למגבלות הזיכרון שצוינו.

תכונות שקשורות לבריאות המערכת

  • הגבלת קצב האתחול: כדי למנוע לולאות אתחול או קריסות חוזרות, pmgd עוקב אחרי סגירת תהליכים ב-/data/misc/pmgd/history.json. הדמון מגביל את התהליכים להפסקת פעולה אחת שיזם pmgd לכל הפעלה מחדש של המכשיר.

הגדרת SELinux

היכולת של PMGD לעקוב אחרי תהליכים מוגבלת על ידי מדיניות SELinux. אם מגדירים את PMGD לניטור תהליך שהדומיין שלו לא מורשה על ידי המדיניות, כמו תהליך מערכת ספציפי לספק, PMGD לא יכול לנטר אותו, ועשויות להופיע ב-logcat דחיות של SELinux.

כדי לאפשר ל-PMGD לנטר תהליכים בדומיינים נוספים, צריך להרחיב את ההרשאות של PMGD על ידי עדכון המדיניות הספציפית למכשיר של SELinux עבור PMGD.

קובץ device/<vendor>/<device>/sepolicy/pmgd.te לדוגמה שמוסיף גישה לדומיין חדש:

# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)

מידע נוסף על כתיבת מדיניות שמותאמת למכשיר ספציפי זמין במאמר בנושא הטמעה של SELinux.

הגדרה שמוגדרת על ידי הספק

ההגדרה של PMGD מבוססת על ספק, ומוגדרת על ידי קובץ JSON נדרש /vendor/etc/pmgd/config.json. בקטע הזה מפורטים התהליכים למעקב, פרופיל מגבלת הזיכרון שהוגדר להם (באמצעות פרופילי משימות של cgroup) ומגבלת הזיכרון האנונימי הקשיחה במגה-בייט.

שדות להגדרת ספקים

הגדרת ה-JSON שסופקה היא רשימה של תהליכים והמגבלות שלהם, שמוגדרים על ידי השדות הבאים:

שדה סוג חובה תיאור ברירת מחדל
target_cmd מחרוזת כן שם הפקודה של תהליך היעד למעקב, לדוגמה, system_server. לא רלוונטי
uid מספר שלם לא מזהה המשתמש (UID) של התהליך. אם לא מציינים את האפשרות הזו, הכלל pmgd חל באופן גלובלי על כל תהליך שתואם ל-target_cmd. לא רלוונטי
reclaim_wait_time_secs מספר שלם לא תקופת החסד בשניות להמתנה עד שהמערכת תפנה זיכרון לפני הערכה חוזרת של מגבלת הזיכרון. 5
mem_limit_profile מחרוזת כן השם של פרופיל המשימות של cgroup שמגדיר את memory.high. נעשה שימוש בפרופיל הזה כדי להגדיר את מגבלת הזיכרון של התהליך. לא רלוונטי
anon_limit_in_mb מספר שלם כן מגבלת הזיכרון האולטימטיבית לאנונימיות במגה-בייט. אם השימוש בזיכרון האנונימי חורג מהערך הזה, pmgd מפסיק את התהליך באופן מיידי. לא רלוונטי
additional_task_profiles רשימת מחרוזות לא רשימה של פרופילים נוספים של משימות ש-pmgd חל עליהם בתהליך כשהמעקב מתחיל. רשימה ריקה

הדוגמה הבאה היא של הגדרת פרופיל משימות של cgroup ב-vendor/etc/task_profiles.json:

{
  "Attributes": [
    ...
    {
      "Name": "MemHigh",
      "Controller": "memory",
      "File": "memory.high"
    }
  ],
  "Profiles": [
    {
      "Name": "SystemServerMemoryHighLimit",
      "Actions": [
        {
          "Name": "SetAttribute",
          "Params":
          {
            "Name": "MemHigh",
            "Value": "1080M"
          }
        }
      ]
    }
  ]
}

הדוגמה הבאה מציגה הגדרה של PMGD ב-vendor/etc/pmgd/config.json:

{
  "targets": [
    {
      "target_cmd": "system_server",
      "uid": 1000,
      "reclaim_wait_time_secs": 5,
      "mem_limit_profile": "SystemServerMemoryHighLimit",
      "anon_limit_in_mb": 300
    }
  ]
}