שיטות מומלצות לניהול זיכרון

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

מבוא

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

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

לפני שפונים לתמיכה

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

מניעת דליפות זיכרון

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

שיטות מומלצות לאפליקציות ל-Android

מוודאים שביצעתם את כל הפעולות הבאות באפליקציה ל-Android:

  1. איך מפרסמים משאבים שלא נמצאים בשימוש
  2. ביטול רישום מאזינים כשאין יותר צורך בהם.
  3. איך מבטלים משימות אם לא צריך
  4. העברת שיטות של מחזור החיים כדי לשחרר משאבים.
  5. שימוש בגרסאות האחרונות של ערכות ה-SDK

בקטעים הבאים תמצאו פרטים ספציפיים לגבי כל אחת מהשיטות האלה.

שחרור משאבים שלא נמצאים בשימוש

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

פרסום הפניות לא עדכניות של מפות Google בערכות GeoSDK

אחת הטעות הנפוצות היא שמפת Google יכולה לגרום לדליפת זיכרון אם היא נשמרה במטמון באמצעות NavigationView או MapView. ל-Google Map יש קשר 1 על 1 עם NavigationView או MapView שמהם הוא אוחזר. עליכם לוודא ש-GoogleMap לא נשמר במטמון, או שההפניה תשוחרר כשמתבצעת קריאה ל-NavigationView#onDestroy או ל-MapView#onDestroy. אם המיקום באמצעות NavigationSupportFragment, MapSupportFragment או מקטע משלך שכולל את התצוגות האלה, ואז צריך לפרסם את קובץ העזר Fragment#onDestroyView.

class NavFragment : SupportNavigationFragment() {

  var googleMap: GoogleMap?

  override fun onCreateView(
    inflater: LayoutInflater,
    parent: ViewGroup?,
    savedInstanceState: Bundle?,
  ): View  {
    super.onCreateView(inflater,parent,savedInstanceState)
    getMapAsync{map -> googleMap = map}
  }

  override fun onDestroyView() {
    googleMap = null
  }
}

ביטול רישום מאזינים כשאין צורך יותר

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

לדוגמה, נניח שהאפליקציה שלך משתמשת ב-SDK לניווט והיא קוראת האזנה לאירועי הגעה: addArrivalListener שיטה להאזנה לאירועי הגעה, היא צריכה גם לקרוא removeArrivalListener כאשר לא צריך יותר לעקוב אחר אירועי ההגעה.

var arrivalListener: Navigator.ArrivalListener? = null

fun registerNavigationListeners() {
  arrivalListener =
    Navigator.ArrivalListener {
      ...
    }
  navigator.addArrivalListener(arrivalListener)
}

override fun onDestroy() {
  navView.onDestroy()
  if (arrivalListener != null) {
    navigator.removeArrivalListener(arrivalListener)
  }

  ...
  super.onDestroy()
}

לבטל משימות כשלא צריך אותן

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

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

העברת שיטות של מחזור החיים לשחרור משאבים

אם האפליקציה שלך משתמשת ב-SDK לניווט או למפות Google, צריך להקפיד לפרסם את על ידי העברת שיטות של מחזור החיים (מוצגות בגופן מודגש) אל navView. אפשר לעשות זאת באמצעות NavigationView ב-SDK לניווט או MapView במפות Google או SDK ניווט. אפשר גם להשתמש ב-SupportNavigationFragment או SupportMapFragment במקום להשתמש ישירות ב-NavigationView וב-MapView, בהתאמה. מקטעי התמיכה מטפלים בהעברה של מחזור החיים שיטות.

class NavViewActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    navView = ...
    navView.onCreate(savedInstanceState)
    ...
  }

  override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)
    navView.onSaveInstanceState(savedInstanceState)
  }

  override fun onTrimMemory(level: Int) {
    super.onTrimMemory(level)
    navView.onTrimMemory(level)
  }

  /* Same with
    override fun onStart()
    override fun onResume()
    override fun onPause()
    override fun onConfigurationChanged(...)
    override fun onStop()
    override fun onDestroy()
  */
}

שימוש בגרסאות האחרונות של ערכות ה-SDK

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

ניפוי באגים של דליפות זיכרון

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

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

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

  1. משחזרים את הבעיה. השלב הזה חיוני לניפוי באגים.
  2. בודקים אם צפוי השימוש בזיכרון. בודקים ש שימוש מוגבר שנראה כדליפה הוא לא הזיכרון שנדרשים להפעלת האפליקציה.
  3. ניפוי באגים ברמה גבוהה. יש כמה כלים שאפשר להשתמש בהם לצורך ניפוי באגים. שלוש קבוצות כלים סטנדרטיות שונות עוזרות לנפות באגים בזיכרון ב-Android: Android Studio, Perfetto ו-Android Debug Bridge (adb) כלי שורת הפקודה (CLI).
  4. איך בודקים את השימוש בזיכרון של האפליקציה אחזור של תמונת מצב של הזיכרון אחר הקצאה, ולאחר מכן לנתח אותו.
  5. פתרון דליפות זיכרון

הקטעים הבאים מתארים את השלבים האלה בפירוט.

שלב 1: משחזרים את הבעיה

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

  • איזו קבוצת תכונות מופעלת?

  • איזה רצף ספציפי של פעולות משתמשים מפעיל את הדליפה?

    • האם ניסית כמה פעמים להפעיל את הרצף הזה?
  • באילו מצבים במחזור החיים האפליקציה עברה מחזור?

    • ניסית כמה חזרות דרך מצבים שונים במחזור החיים?

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

שלב 2: בודקים אם האפליקציה צפויה להשתמש בזיכרון

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

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

  • השימוש הצפוי בזיכרון: הזיכרון מוחזר בעקבות התרחיש הופסק.

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

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

שלב 3: ניפוי באגים ברמה גבוהה

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

הכלי לניתוח זיכרון של Android Studio

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

מוני זיכרון Perfetto

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

ממשק משתמש של Perfetto

כלי שורת הפקודה לניפוי באגים ב-Android (adb)

הרבה הדברים שאפשר לעקוב אחריהם ב-Perfetto זמינים גם בתור adb שירות שורת פקודה שאפשר להריץ עליו שאילתה ישירות. כמה נקודות חשובות הנה כמה דוגמאות:

  • Meminfo מאפשר לך לראות מידע מפורט על הזיכרון בנקודת זמן מסוימת.

  • המונח Procstats מספק נתונים סטטיסטיים מצטברים חשובים לאורך זמן.

נתון סטטיסטי חשוב שיש לבחון כאן הוא טביעת הרגל הפחמנית המקסימלית של הזיכרון הפיזי (maxRSS) שהאפליקציה דורשת לאורך זמן. ייתכן ש-MaxPSS לא יהיה מדויק באותה מידה. עבור דרך לשיפור הדיוק, סימון adb shell dumpsys procstats --help –start-testing.

מעקב אחרי הקצאה

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

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

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

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

  1. צילום תמונת מצב של הזיכרון.
  2. ניתוח של תמונת מצב של הזיכרון כדי לאתר דליפות זיכרון
  3. תיקון דליפות זיכרון

בסעיפים הבאים יש מידע נוסף בנושא.

צילום של תמונת מצב של הזיכרון

כדי לתעד תמונת מצב של הזיכרון, אפשר להשתמש ב-Android Debug Bridge (adb) או הכלי לניתוח זיכרון של Android Studio.

שימוש ב-adb כדי לתעד תמונת מצב של הזיכרון

כדי לצלם תמונת מצב של הזיכרון באמצעות adb, יש לבצע את השלבים הבאים:

  1. מחברים את מכשיר Android למחשב.
  2. פותחים את שורת הפקודה ועוברים לספרייה שבה נמצאים כלי ה-adb.
  3. כדי לצלם תמונת מצב של הזיכרון, מריצים את הפקודה הבאה :

    adb shell am dumpheap my.app.name $PHONE_FILE_OUT

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

    adb pull $PHONE_FILE_OUT $LOCAL_FILE.

שימוש ב-Android Studio כדי לתעד תמונת מצב של הזיכרון

כדי לצלם תמונת מצב של הזיכרון באמצעות הכלי לניתוח זיכרון של Android Studio, פועלים לפי השלבים הבאים ב-Android, צילום של תמונת מצב של הזיכרון .

איך לנתח את תמונת המצב של הזיכרון כדי לאתר דליפות זיכרון

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

  1. פותחים את פרויקט Android ב-Android Studio.

  2. בוחרים באפשרות Run (הפעלה) ולאחר מכן בוחרים בהגדרה Debug (ניפוי באגים).

  3. פותחים את הכרטיסייה Android Profiler.

  4. בוחרים באפשרות זיכרון.

  5. בוחרים באפשרות פתיחת תמונת מצב של הזיכרון ובוחרים את הקובץ של תמונת המצב של הזיכרון שיצרתם. בכלי לפרופיל הזיכרון מוצג תרשים של השימוש בזיכרון של האפליקציה.

  6. משתמשים בתרשים כדי לנתח את תמונת המצב של הזיכרון:

    • זיהוי אובייקטים שכבר לא נמצאים בשימוש.

    • זיהוי אובייקטים שצורכים הרבה זיכרון.

    • אפשר לראות בכמה זיכרון משתמש כל אובייקט.

  7. אפשר להשתמש במידע הזה כדי לצמצם או לאתר את המקור של דליפת הזיכרון ולתקן את הבעיה.

שלב 5: תיקון דליפות זיכרון

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

כלים אחרים לניפוי באגים

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

ניפוי באגים בזיכרון בקוד נייטיב עם מעקב הקצאה

גם אם אתם לא משתמשים ישירות בקוד נייטיב, יש כמה ספריות נפוצות של Android כולל ערכות SDK של Google. אם אתם חושבים שדליפת הזיכרון נבעה מקוד נייטיב, יש כמה כלים שאפשר להשתמש בהם כדי לנפות באגים. מעקב אחר הקצאות באמצעות Android Studio או heapprofd (תואם גם ל-Perfetto) הוא דרך מצוינת לזהות סיבות אפשריות לדליפת זיכרון, ולרוב זו הדרך המהירה ביותר לניפוי באגים.

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

זיהוי הדלפות באמצעות LeakCanary

LeakCanary היא כלי עוצמתי לזיהוי דליפות זיכרון באפליקציות ל-Android. מידע נוסף על השימוש ב-LeakCanary באפליקציה שלכם זמין בכתובת LeakCanary.

איך לדווח על בעיות בערכות SDK של Google

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

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

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

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

  • דוח על באג שנוצר אחרי שיצרתם מחדש את התנאי של הדליפה.

  • דוח קריסות של קריסות שקשורות לזיכרון.

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