برای مشاهده اینکه کدام اشیاء در برنامه شما در زمان ضبط از حافظه استفاده می کنند، یک پشته را ضبط کنید و نشت حافظه یا رفتار تخصیص حافظه که منجر به لکنت، فریز و حتی خرابی برنامه می شود را شناسایی کنید. پس از یک جلسه طولانی کاربر، زمانی که می تواند اشیایی را که در حافظه هستند و دیگر نباید وجود داشته باشند را نشان می دهد، به خصوص مفید است.
این صفحه ابزاری را که Android Studio برای جمعآوری و تجزیه و تحلیل heap dump ارائه میکند، توضیح میدهد. همچنین، میتوانید حافظه برنامه خود را از خط فرمان با dumpsys
بررسی کنید و همچنین رویدادهای جمعآوری زباله (GC) را در Logcat ببینید .
چرا باید حافظه برنامه خود را نمایه کنید
Android یک محیط حافظه مدیریت شده را فراهم می کند — وقتی Android تشخیص می دهد که برنامه شما دیگر از برخی اشیاء استفاده نمی کند، زباله جمع کننده حافظه استفاده نشده را به پشته باز می کند. نحوه یافتن حافظه استفاده نشده اندروید به طور مداوم در حال بهبود است، اما در برخی از نسخههای اندروید، سیستم باید برای مدت کوتاهی کد شما را متوقف کند. بیشتر اوقات، مکث ها غیرقابل درک است. با این حال، اگر برنامه شما سریعتر از آنچه سیستم میتواند آن را جمعآوری کند، حافظه را تخصیص میدهد، ممکن است برنامه شما به تأخیر بیفتد در حالی که جمعآورنده حافظه کافی برای برآورده کردن تخصیصهای شما آزاد میکند. تأخیر ممکن است باعث شود برنامه شما فریم ها را رد کند و باعث کندی قابل مشاهده شود.
حتی اگر برنامه شما کندی را نشان نمیدهد، اگر حافظهاش نشت کند، میتواند آن حافظه را حتی زمانی که در پسزمینه است حفظ کند. این رفتار میتواند با تحمیل رویدادهای جمعآوری زباله غیرضروری، بقیه عملکرد حافظه سیستم را کاهش دهد. در نهایت، سیستم مجبور می شود برای بازیابی حافظه، فرآیند برنامه شما را از بین ببرد. سپس هنگامی که کاربر به برنامه شما بازگشت، فرآیند برنامه باید به طور کامل راه اندازی مجدد شود.
برای کسب اطلاعات در مورد شیوههای برنامهنویسی که میتوانند استفاده از حافظه برنامه شما را کاهش دهند، مدیریت حافظه برنامه خود را بخوانید.
بررسی اجمالی زباله
برای گرفتن یک heap dump، تکلیف Analyze Memory Usage (Heap Dump) را انتخاب کنید ( از Profiler استفاده کنید: «app» را بهعنوان قابل اشکالزدایی (دادههای کامل) اجرا کنید ) تا یک Heap Dump را ضبط کنید. در حین تخلیه پشته، مقدار حافظه جاوا ممکن است به طور موقت افزایش یابد. این طبیعی است زیرا heap dump در همان فرآیند برنامه شما رخ می دهد و برای جمع آوری داده ها به مقداری حافظه نیاز دارد. پس از گرفتن heap dump، موارد زیر را مشاهده می کنید:
لیست کلاس ها اطلاعات زیر را نشان می دهد:
- تخصیص ها : تعداد تخصیص ها در پشته.
Native Size : کل مقدار حافظه بومی مورد استفاده این نوع شی (بر حسب بایت). در اینجا حافظه برخی از اشیاء اختصاص داده شده در جاوا را خواهید دید زیرا Android از حافظه بومی برای برخی از کلاس های فریمورک مانند
Bitmap
استفاده می کند.اندازه کم عمق : مقدار کل حافظه جاوای استفاده شده توسط این نوع شی (بر حسب بایت).
Retained Size : اندازه کل حافظه ای که به دلیل تمام نمونه های این کلاس (بر حسب بایت) حفظ می شود.
از منوی پشته برای فیلتر کردن انبوه های خاص استفاده کنید:
- پشته برنامه (پیشفرض) : پشته اصلی که برنامه شما حافظه را به آن اختصاص میدهد.
- Image Heap : تصویر بوت سیستم، حاوی کلاس هایی است که در زمان بوت از قبل بارگذاری شده اند. تخصیص ها در اینجا هرگز جابجا نمی شوند یا از بین نمی روند.
- Zygote heap : پشته کپی در نوشتن که در آن فرآیند برنامه از سیستم اندروید فوک می شود.
از منوی کشویی آرایش برای انتخاب نحوه ترتیب دادن تخصیص ها استفاده کنید:
- ترتیب بر اساس کلاس (پیش فرض) : همه تخصیص ها را بر اساس نام کلاس گروه بندی می کند.
- ترتیب بر اساس بسته : همه تخصیص ها را بر اساس نام بسته گروه بندی می کند.
از منوی کشویی کلاس برای فیلتر کردن گروه های کلاس استفاده کنید:
- همه کلاسها (پیشفرض) : همه کلاسها، از جمله کلاسهای کتابخانهها و وابستگیها را نشان میدهد.
- نمایش فعالیت/نشت قطعه : کلاس هایی را نشان می دهد که باعث نشت حافظه می شوند.
- نمایش کلاس های پروژه : فقط کلاس های تعریف شده توسط پروژه شما را نشان می دهد.
روی نام کلاس کلیک کنید تا پنجره Instance باز شود. هر نمونه لیست شده شامل موارد زیر است:
- عمق : کوتاه ترین تعداد پرش از هر ریشه GC تا نمونه انتخاب شده.
- Native Size : اندازه این نمونه در حافظه اصلی. این ستون فقط برای اندروید 7.0 و بالاتر قابل مشاهده است.
- Shallow Size : اندازه این نمونه در حافظه جاوا.
- Retained Size : اندازه حافظه ای که این نمونه بر آن غالب است (طبق درخت غالب ).
برای نمایش جزئیات نمونه ، از جمله فیلدها و مراجع ، روی یک نمونه کلیک کنید. انواع فیلد و مرجع رایج انواع ساختاری هستند ، آرایه ها و انواع داده های اولیه در جاوا روی یک فیلد یا مرجع کلیک راست کنید تا به نمونه یا خط مرتبط در کد منبع بروید.
- فیلدها : تمام فیلدهای این نمونه را نشان می دهد.
- References : هر ارجاع به شی مشخص شده در تب Instance را نشان می دهد.
نشت حافظه را پیدا کنید
برای فیلتر کردن سریع کلاسهایی که ممکن است با نشت حافظه مرتبط باشند، منوی کشویی کلاس را باز کرده و Show activity/fragment leaks را انتخاب کنید. Android Studio کلاس هایی را نشان می دهد که فکر می کند نشان دهنده نشت حافظه برای نمونه های Activity
و Fragment
در برنامه شما هستند. انواع داده هایی که فیلتر نشان می دهد شامل موارد زیر است:
- نمونههای
Activity
که از بین رفتهاند اما هنوز به آنها ارجاع داده میشود. - نمونه های
Fragment
کهFragmentManager
معتبری ندارند اما همچنان به آنها ارجاع داده می شود.
توجه داشته باشید که فیلتر ممکن است در شرایط زیر مثبت کاذب باشد:
- یک
Fragment
ایجاد شده است اما هنوز استفاده نشده است. - یک
Fragment
در حافظه پنهان ذخیره می شود، اما نه به عنوان بخشی از یکFragmentTransaction
.
برای جستجوی نشت حافظه به صورت دستی، فهرست کلاسها و نمونهها را مرور کنید تا اشیایی با اندازه حفظ شده بزرگ پیدا کنید. به دنبال نشت حافظه ناشی از هر یک از موارد زیر باشید:
- ارجاع طولانی مدت به
Activity
،Context
،View
،Drawable
و سایر اشیایی که ممکن است ارجاعی بهActivity
یاContext
داشته باشند. - کلاسهای داخلی غیراستاتیک، مانند
Runnable
، که میتوانند یک نمونهActivity
را نگه دارند. - حافظه های پنهانی که اشیاء را بیش از حد لازم نگه می دارند.
هنگامی که نشت حافظه احتمالی را پیدا کردید، از تب فیلدها و مراجع در جزئیات نمونه استفاده کنید تا به خط نمونه یا کد منبع مورد علاقه بروید.
باعث نشت حافظه برای آزمایش شود
برای تجزیه و تحلیل میزان استفاده از حافظه، باید روی کد برنامه خود تاکید کنید و سعی کنید اجباری نشت حافظه را ایجاد کنید. یکی از راههای برانگیختن نشت حافظه در برنامهتان این است که قبل از بررسی پشته، اجازه دهید مدتی اجرا شود. نشت ممکن است به بالای تخصیص در پشته برسد. با این حال، هر چه نشتی کوچکتر باشد، برای دیدن برنامه به مدت زمان بیشتری نیاز دارید.
همچنین می توانید نشت حافظه را به یکی از روش های زیر راه اندازی کنید:
- دستگاه را از حالت عمودی به منظره بچرخانید و در حالت های مختلف فعالیت چندین بار به عقب برگردید. چرخاندن دستگاه اغلب میتواند باعث لو رفتن یک شیء
Activity
،Context
یاView
در برنامه شود زیرا سیستمActivity
را دوباره ایجاد میکند، و اگر برنامه شما به یکی از آن اشیاء در جای دیگری ارجاع داشته باشد، سیستم نمیتواند آن را جمعآوری کند. - زمانی که در حالتهای فعالیت مختلف هستید، بین برنامه خود و برنامه دیگری جابهجا شوید. به عنوان مثال، به صفحه اصلی بروید، سپس به برنامه خود بازگردید.
صادرات و واردات یک رکورد تخلیه پشته
میتوانید یک فایل heap dump را از برگه ضبطهای گذشته در پروفایلر صادر و وارد کنید . Android Studio ضبط را به عنوان یک فایل .hprof
ذخیره می کند.
از طرف دیگر، برای استفاده از یک تحلیلگر فایل .hprof
متفاوت مانند jhat ، باید فایل .hprof
را از فرمت Android به فرمت فایل Java SE .hprof
تبدیل کنید. برای تبدیل فرمت فایل، از ابزار hprof-conv
ارائه شده در فهرست راهنمای {android_sdk}/platform-tools/
استفاده کنید. دستور hprof-conv
را با دو آرگومان اجرا کنید: نام فایل .hprof
اصلی و محل نوشتن فایل .hprof
تبدیل شده، از جمله نام فایل .hprof
جدید. به عنوان مثال:
hprof-conv heap-original.hprof heap-converted.hprof