ב-Android 17 ואילך יש תמיכה בשד PMGD (process memory guardian daemon), שמגן על תקינות המערכת ועל חוויית המשתמש על ידי ניהול פרואקטיבי של השימוש בזיכרון על בסיס כל תהליך. הדמון משפר את היציבות הכוללת של המכשיר על ידי אכיפה הדרגתית של מגבלות זיכרון בתהליכי יעד ספציפיים, ומוודא שדליפות זיכרון או עליות חדות בשימוש בזיכרון לא יגרמו לירידה בביצועים ברמת המערכת.
בעוד שרוצחי זיכרון גלובליים רגילים פועלים רק כשהמערכת כולה נמצאת תחת לחץ, PMGD נוקט גישה גרנולרית. הדמון מבצע את זה על ידי מעקב אחרי ערכי הזיכרון של קבוצת הבקרה v2 עבור תהליכי היעד שלו.
כשתהליך ממוקד חורג ממגבלות הזיכרון שהוגדרו לו, pmgd
מטפל בהפרות של מגבלות על ידי רישום של אטומי זיכרון של Statsd לפני סיום התהליך.
איך זה עובד
הדמון משתמש ב-inotify כדי להאזין לאירועים של עומס על הזיכרון (במיוחד פעילות של שימוש בזיכרון גבוה באמצעות memory.events). כשמתרחש אירוע זיכרון בתהליך שבמעקב, pmgd מבצע את הפעולות הבאות:
- בדיקת זיכרון אנונימית: מעריכה את הזיכרון האנונימי של התהליך. אם הוא חורג מהערך המוגדר של
anon_limit_in_mb, pmgdמפסיק את התהליך באופן מיידי. - תקופת המתנה להחזרת זיכרון: אם הזיכרון האנונימי נמוך ממגבלת הזיכרון האנונימי שצוינה,
pmgdממתין לתקופת חסד להחזרת זיכרון על ידי המערכת (reclaim_wait_time_secs). - הערכת הזיכרון אחרי השחרור: אם הערך של
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
}
]
}