זיהוי Jank הקשור לריצוף

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

עיכוב מתזמן שרשור יישום

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

  • שרשור עוזר אקראי באפליקציה יכול כנראה להתעכב במשך אלפיות שניות רבות ללא בעיה.
  • שרשור ממשק המשתמש של יישום עשוי לסבול 1-2ms של ריצוד.
  • מנהלי התקן kthreads הפועלים כ-SCHED_FIFO עלולים לגרום לבעיות אם הם ניתנים להרצה עבור 500us לפני ההפעלה.

ניתן לזהות זמני ריצה ב-systrace לפי הפס הכחול שלפני קטע רץ של חוט. זמן ריצה יכול להיקבע גם על פי משך הזמן בין אירוע sched_wakeup עבור שרשור לאירוע sched_switch המאותת על תחילת ביצוע השרשור.

שרשורים שנמשכים יותר מדי

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

  1. השתמש בערכות cpuss כמתואר במצערת תרמית .
  2. הגדל את הערך CONFIG_HZ.
    • היסטורית, הערך נקבע ל-100 בפלטפורמות arm ו-arm64. עם זאת, זוהי תאונה של היסטוריה ואינו ערך טוב לשימוש עבור מכשירים אינטראקטיביים. CONFIG_HZ=100 פירושו ש-Jiffy הוא באורך של 10ms, מה שאומר שאיזון עומסים בין מעבדים עשוי לקחת 20ms (שתי Jiffies) להתרחש. זה יכול לתרום באופן משמעותי לשטף במערכת עמוסה.
    • מכשירים אחרונים (Nexus 5X, Nexus 6P, Pixel ו-Pixel XL) נשלחו עם CONFIG_HZ=300. זה אמור להיות בעל עלות כוח זניחה תוך שיפור משמעותי בזמני הריצה. אם אתה אכן רואה עליות משמעותיות בצריכת החשמל או בבעיות בביצועים לאחר שינוי CONFIG_HZ, סביר להניח שאחד מהנהגים שלך משתמש בטיימר המבוסס על Jiffies גולמי במקום אלפיות שניות וממיר ל-Jiffies. זה בדרך כלל תיקון קל (ראה את התיקון שתיקן בעיות בטיימר kgsl ב-Nexus 5X ו-6P בעת המרה ל-CONFIG_HZ=300).
    • לבסוף, ניסינו עם CONFIG_HZ=1000 ב-Nexus/Pixel וגילינו שהוא מציע ביצועים והפחתת הספק ניכרים עקב ירידה בתקורה של RCU.

עם שני השינויים האלה בלבד, מכשיר אמור להיראות הרבה יותר טוב עבור זמן ריצה של חוט ממשק משתמש תחת עומס.

שימוש ב-sys.use_fifo_ui

אתה יכול לנסות להעלות את זמן הריצה של שרשור ממשק משתמש לאפס על ידי הגדרת המאפיין sys.use_fifo_ui ל-1.

אזהרה : אל תשתמש באפשרות זו בתצורות CPU הטרוגניות אלא אם כן יש לך מתזמן RT מודע לקיבולת. וברגע זה, אף מתזמן RT המשלוח אינו מודע לקיבולת . אנחנו עובדים על אחד עבור EAS, אבל הוא עדיין לא זמין. מתזמן RT המוגדר כברירת מחדל מבוסס אך ורק על עדיפויות RT והאם ל-CPU כבר יש חוט RT בעל עדיפות שווה או גבוהה יותר.

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

כאשר sys.use_fifo_ui מופעל, ActivityManager עוקב אחר שרשור ממשק המשתמש ו-RenderThread (שני השרשורים הקריטיים ביותר לממשק המשתמש) של היישום העליון והופך את השרשורים הללו ל-SCHED_FIFO במקום SCHED_OTHER. זה מבטל למעשה ריצוד מממשק המשתמש ומ-RenderThreads; העקבות שאספנו עם אפשרות זו מופעלת מציגים זמני ריצה בסדר גודל של מיקרו-שניות במקום אלפיות שניות.

עם זאת, מכיוון שמאזן העומס RT לא היה מודע לקיבולת, חלה הפחתה של 30% בביצועי ההפעלה של האפליקציה מכיוון שהחוט של ממשק המשתמש האחראי על הפעלת האפליקציה יועבר מליבת Kryo מוזהבת 2.1Ghz לליבה Kryo כסופה במהירות 1.5GHz . עם מאזן עומסים RT מודע לקיבולת, אנו רואים ביצועים מקבילים בפעולות בכמות גדולה והפחתה של 10-15% בזמני הפריימים של האחוזון ה-95 וה-99 ברבים ממדדי ממשק המשתמש שלנו.

להפריע לתנועה

מכיוון שפלטפורמות ARM מספקות פסיקות ל-CPU 0 כברירת מחדל בלבד, אנו ממליצים להשתמש במאזן IRQ (irqbalance או msm_irqbalance בפלטפורמות של קוואלקום).

במהלך הפיתוח של Pixel, ראינו ג'אנק שניתן לייחס ישירות למעבד 0 המכריע עם הפרעות. לדוגמה, אם השרשור mdss_fb0 תוכנן ל-CPU 0, הייתה סבירות גבוהה בהרבה ל-jank בגלל הפרעה שמופעלת על ידי התצוגה כמעט מיד לפני הסריקה. mdss_fb0 יהיה באמצע העבודה שלו עם דדליין מאוד צפוף, ואז הוא יאבד קצת זמן למטפל בפסיקות MDSS. בתחילה, ניסינו לתקן זאת על ידי הגדרת זיקת ה-CPU של פתיל mdss_fb0 למעבדים 1-3 כדי למנוע מחלוקת עם ההפרעה, אבל אז הבנו שעדיין לא הפעלנו את msm_irqbalance. כאשר msm_irqbalance מופעל, ה-jank השתפר בצורה ניכרת גם כאשר גם mdss_fb0 וגם פסיקת ה-MDSS היו על אותו מעבד עקב מחלוקת מופחתת מפסיקות אחרות.

ניתן לזהות זאת ב-systrace על ידי התבוננות בקטע התזמון וכן בקטע ה-irq. מקטע התזמון מראה את מה שתוזמן, אבל אזור חופף בקטע ה-irq אומר שהפרעה פועלת במהלך הזמן הזה במקום התהליך המתוזמן בדרך כלל. אם אתה רואה נתחי זמן משמעותיים שלוקחים במהלך הפרעה, האפשרויות שלך כוללות:

  • הפוך את מטפל ההפרעות למהיר יותר.
  • מנע את ההפרעה מלכתחילה.
  • שנה את תדירות ההפסקה כך שתהיה מחוץ לשלב עם עבודה רגילה אחרת שהיא עשויה להפריע לה (אם מדובר בהפסקה רגילה).
  • הגדר את זיקת ה-CPU של ההפרעה ישירות ומונע ממנה להיות מאוזנת.
  • הגדר את זיקת ה-CPU של השרשור שאליו ההפרעה מפריעה כדי למנוע את ההפרעה.
  • הסתמכו על מאזן ההפרעות כדי להעביר את ההפרעה למעבד פחות עמוס.

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

softirqs ארוך

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


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

נהגים עוזבים את ה-preemption או IRQs מושבתים זמן רב מדי

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

כמה קווים מנחים:

  • אם השרשור הניתן להרצה הוא SCHED_FIFO והשרשור המופעל הוא SCHED_OTHER, השרשור המופעל מושבת.
  • אם השרשור הניתן להרצה נמצא בעדיפות גבוהה משמעותית (100) מהשרשור המופעל (120), סביר להניח שהשרשור המופעל מושבת אם השרשור הניתן להרצה אינו פועל תוך שתי זריקות.
  • אם לשרשור הניתן להרצה ולשרשור הפועל יש אותה עדיפות, סביר להניח שהשרשור המופעל מושבת אם השרשור הניתן להרצה אינו פועל תוך 20 שניות.

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


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

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

מטפלי פסיקות צריכים לעתים קרובות לעשות עבודה שיכולה לפעול מחוץ להקשר של פסיקה, מה שמאפשר להעביר עבודה לשרשורים שונים בקרנל. מפתח מנהלי התקנים עשוי להבחין שלקרנל יש פונקציונליות של משימות אסינכרוניות נוחה מאוד בכל המערכת הנקראת workqueues ועשויה להשתמש בה לעבודה הקשורה לפסיקה.

עם זאת, תורי עבודה הם כמעט תמיד התשובה השגויה לבעיה זו מכיוון שהם תמיד SCHED_OTHER. הפרעות חומרה רבות נמצאות בנתיב הקריטי של ביצועים ויש להפעילן מיד. לתורי עבודה אין ערובה לגבי מתי הם יופעלו. בכל פעם שראינו תור עבודה בנתיב הקריטי של ביצועים, זה היה מקור לבלבול ספורדי, ללא קשר למכשיר. ב-Pixel, עם מעבד דגל, ראינו שתור עבודה בודד יכול להתעכב עד 7ms אם המכשיר היה תחת עומס בהתאם להתנהגות המתזמן ודברים אחרים הפועלים במערכת.

במקום תור עבודה, מנהלי התקנים שצריכים לטפל בעבודה דמוית פסיקה בתוך שרשור נפרד צריכים ליצור kthread SCHED_FIFO משלהם. לקבלת עזרה לעשות זאת עם פונקציות kthread_work, עיין בתיקון זה.

מחלוקת על נעילת מסגרת

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

מחלוקת מנעול קלסר

מבחינה היסטורית, לקלסר היה מנעול עולמי יחיד. אם החוט המריץ עסקת קלסר הוקדם בזמן החזקת המנעול, אף חוט אחר לא יכול לבצע עסקת קלסר עד שהחוט המקורי ישחרר את המנעול. זה רע; מחלוקת קלסר יכולה לחסום כל דבר במערכת, כולל שליחת עדכוני ממשק משתמש לתצוגה (שרשורי ממשק משתמש מתקשרים עם SurfaceFlinger באמצעות קלסר).

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

מחלוקת fd בתוך תהליך

זה נדיר. הג'אנק שלך כנראה לא נגרם בגלל זה.

עם זאת, אם יש לך שרשורים מרובים בתהליך שכותבים את אותו ה-FD, אפשר לראות מחלוקת על ה-FD הזה, אולם הפעם היחידה שראינו זאת במהלך העלאת Pixel היא במהלך בדיקה שבה שרשורים בעדיפות נמוכה ניסו לכבוש את כל ה-CPU זמן בזמן שרשור אחד בעדיפות גבוהה פעל באותו תהליך. כל החוטים נכתבו לסמן העקבות fd והחוט בעדיפות גבוהה עלול להיחסם על סמן העקיבה fd אם חוט בעדיפות נמוכה החזיק את נעילת ה-fd ולאחר מכן הוקדם. כאשר המעקב הושבת מהשרשורים בעדיפות נמוכה, לא הייתה בעיה בביצועים.

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

מעברי סרק מיותרים של המעבד

כאשר עוסקים ב-IPC, במיוחד צינורות מרובי-תהליכים, נפוץ לראות וריאציות על התנהגות זמן הריצה הבאה:

  1. שרשור A פועל על CPU 1.
  2. שרשור א' מעורר שרשור ב'.
  3. שרשור B מתחיל לפעול במעבד 2.
  4. חוט א' הולך מיד לישון, כדי שיעיר אותו חוט ב' כאשר חוט ב' סיים את עבודתו הנוכחית.

מקור תקורה נפוץ הוא בין שלבים 2 ו-3. אם מעבד 2 אינו פעיל, יש להחזירו למצב פעיל לפני שהשרשור B יוכל לפעול. תלוי ב-SOC ובעומק הבטלה, זה יכול להיות עשרות מיקרו-שניות לפני שרשור B מתחיל לפעול. אם זמן הריצה בפועל של כל צד של ה-IPC קרוב מספיק לתקורה, הביצועים הכוללים של אותו צינור יכולים להיות מופחתים באופן משמעותי על ידי מעברי סרק של CPU. המקום הנפוץ ביותר עבור אנדרואיד לפגוע בזה הוא סביב עסקאות קלסר, ושירותים רבים המשתמשים בקלסר בסופו של דבר נראים כמו המצב שתואר לעיל.

ראשית, השתמש בפונקציה wake_up_interruptible_sync() במנהלי התקנים של הליבה שלך ותמך בכך מכל מתזמן מותאם אישית. התייחס לזה כדרישה, לא כאל רמז. Binder משתמש בזה היום, וזה עוזר מאוד עם עסקאות קלסר סינכרוניות תוך הימנעות ממעברי סרק מיותרים של CPU.

שנית, ודא כי זמני המעבר של cpuidle שלך ​​הם מציאותיים ומושל cpuidle לוקח אותם בחשבון בצורה נכונה. אם ה-SOC שלך חובט פנימה והחוצה ממצב הסרק העמוק ביותר שלך, לא תחסוך בחשמל על ידי מעבר למצב הסרק העמוק ביותר.

רישום

הרישום אינו פנוי עבור מחזורי CPU או זיכרון, אז אל תשלח דואר זבל למאגר היומן. רישום עלויות מחזורי ביישום שלך (ישירות) ובדמון היומן. הסר כל יומני ניפוי באגים לפני משלוח המכשיר שלך.

בעיות קלט/פלט

פעולות I/O הן מקורות נפוצים של ריצוד. אם שרשור ניגש לקובץ ממופה זיכרון והעמוד לא נמצא במטמון העמוד, הוא פגום וקורא את העמוד מהדיסק. זה חוסם את השרשור (בדרך כלל במשך 10+ אלפיות השנייה) ואם זה קורה בנתיב הקריטי של רינדור ממשק המשתמש, יכול לגרום ל- Jannk. יש יותר מדי סיבות לפעולות קלט/פלט מכדי לדון בהן כאן, אבל בדוק את המיקומים הבאים כשמנסים לשפר את התנהגות הקלט/פלט:

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

    במכשירי Pixel ו-Nexus 6P עם אנדרואיד 7.0, אספנו ארבעה קבצים:
    • /system/framework/arm64/boot-framework.oat
    • /system/framework/oat/arm64/services.odex
    • /system/framework/arm64/boot.oat
    • /system/framework/arm64/boot-core-libart.oat
    קבצים אלה נמצאים בשימוש מתמיד על ידי רוב היישומים ו-system_server, ולכן אין לדפדף אותם. בפרט, גילינו שאם אחד מאלה יורחק החוצה, הם יוכנסו חזרה ויגרמו לדחיסה בעת מעבר מיישום בעל משקל כבד.
  • הצפנה . סיבה אפשרית נוספת לבעיות קלט/פלט. אנו מוצאים שהצפנה מוטבעת מציעה את הביצועים הטובים ביותר בהשוואה להצפנה מבוססת מעבד או שימוש בבלוק חומרה הנגיש באמצעות DMA. והכי חשוב, הצפנה מוטבעת מפחיתה את הריצוד הקשור ל-I/O, במיוחד בהשוואה להצפנה מבוססת CPU. מכיוון שהאחזורים למטמון הדף נמצאים לרוב בנתיב הקריטי של עיבוד ממשק המשתמש, הצפנה מבוססת מעבד מציגה עומס מעבד נוסף בנתיב הקריטי, מה שמוסיף יותר ריצוד מאשר רק אחזור ה-I/O.

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

אריזת משימות קטנות אגרסיביות

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

מטמון דפים

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

אחת הדרכים לזהות זאת היא לקחת סיסטטראס באמצעות תג pagecache והזנה שמתחקות אל הסקריפט בכתובת system/extras/pagecache/pagecache.py . pagecache.py מתרגם בקשות בודדות למיפוי קבצים לתוך מטמון הדף לסטטיסטיקה מצטברת לכל קובץ. אם אתה מגלה שנקראו יותר בתים של קובץ מהגודל הכולל של הקובץ בדיסק, אתה בהחלט פוגע במטמון העמודים.

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

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

  • השתמש בפחות זיכרון בתהליכים מתמשכים. ככל שתהליכים מתמשכים משתמשים בפחות זיכרון, כך זמין יותר זיכרון לאפליקציות ולמטמון העמודים.
  • בדוק את ההגדרות שיש לך עבור המכשיר שלך כדי לוודא שאינך מסיר זיכרון ממערכת ההפעלה שלא לצורך. ראינו מצבים שבהם ניפוי באגים הושארו בטעות בתצורות גרעין המשלוח, וצורכים עשרות מגה-בייט של זיכרון. זה יכול לעשות את ההבדל בין פגיעה במטמון של דפים ובין לא, במיוחד במכשירים עם פחות זיכרון.
  • אם אתה רואה את המטמון של עמודים ב-system_server בקבצים קריטיים, שקול להצמיד קבצים אלה. זה יגביר את לחץ הזיכרון במקומות אחרים, אבל זה עשוי לשנות את ההתנהגות מספיק כדי להימנע מהתנגשות.
  • כוונן מחדש את lowmemorykiller כדי לנסות לשמור על יותר זיכרון פנוי. הספים של lowmemorykiller מבוססים הן על זיכרון פנוי מוחלט והן על מטמון העמודים, כך שהגדלת הסף שבו תהליכים ברמת oom_adj נתונה מומתים עשויה לגרום להתנהגות טובה יותר על חשבון מוות מוגבר של אפליקציות ברקע.
  • נסה להשתמש ב-ZRAM. אנו משתמשים ב-ZRAM ב-Pixel, למרות שלפיקסל יש 4GB, מכיוון שהוא יכול לעזור עם דפים מלוכלכים בשימוש נדיר.