یک توده زباله را ضبط کنید

یک heap dump را ضبط کنید تا ببینید کدام اشیاء در برنامه شما در زمان ضبط از حافظه استفاده می‌کنند و نشت حافظه یا رفتار تخصیص حافظه را که منجر به لکنت، هنگ کردن و حتی خرابی برنامه می‌شود، شناسایی کنید. گرفتن heap dumpها به ویژه پس از یک جلسه طولانی کاربر مفید است، زمانی که می‌تواند اشیاء موجود در حافظه را نشان دهد که دیگر نباید آنجا باشند.

این صفحه ابزاری را که اندروید استودیو برای جمع‌آوری و تحلیل داده‌های هیپ ارائه می‌دهد، شرح می‌دهد. به عنوان یک روش جایگزین، می‌توانید حافظه برنامه خود را از خط فرمان با dumpsys بررسی کنید و همچنین رویدادهای جمع‌آوری زباله (GC) را در Logcat مشاهده کنید .

چرا باید حافظه برنامه خود را پروفایل کنید

اندروید یک محیط مدیریت‌شده‌ی حافظه ارائه می‌دهد - وقتی اندروید تشخیص می‌دهد که برنامه‌ی شما دیگر از برخی اشیاء استفاده نمی‌کند، زباله‌روب حافظه‌ی استفاده‌نشده را به حافظه‌ی هیپ (heap) برمی‌گرداند. نحوه‌ی پیدا کردن حافظه‌ی استفاده‌نشده در اندروید دائماً در حال بهبود است، اما در برخی از نسخه‌های اندروید، سیستم باید کد شما را به طور خلاصه متوقف کند. اغلب اوقات، این توقف‌ها غیرقابل مشاهده هستند. با این حال، اگر برنامه‌ی شما حافظه را سریع‌تر از آنچه سیستم می‌تواند جمع‌آوری کند، اختصاص دهد، ممکن است برنامه‌ی شما در حالی که زباله‌روب حافظه‌ی کافی برای برآورده کردن تخصیص‌های شما را آزاد می‌کند، به تأخیر بیفتد. این تأخیر می‌تواند باعث شود برنامه‌ی شما فریم‌ها را رد کند و باعث کندی قابل مشاهده شود.

حتی اگر برنامه شما کندی نشان ندهد، اگر دچار نشت حافظه شود، می‌تواند آن حافظه را حتی در حالی که در پس‌زمینه است، حفظ کند. این رفتار می‌تواند با مجبور کردن رویدادهای جمع‌آوری زباله غیرضروری، عملکرد بقیه حافظه سیستم را کند کند. در نهایت، سیستم مجبور می‌شود فرآیند برنامه شما را برای بازیابی حافظه متوقف کند. سپس وقتی کاربر به برنامه شما برمی‌گردد، فرآیند برنامه باید به طور کامل مجدداً راه‌اندازی شود.

برای کسب اطلاعات در مورد شیوه‌های برنامه‌نویسی که می‌توانند استفاده از حافظه برنامه شما را کاهش دهند، مدیریت حافظه برنامه خود را مطالعه کنید.

نمای کلی از هیپ دامپ

برای گرفتن یک heap dump، وظیفه Analyze Memory Usage (Heap Dump) را انتخاب کنید ( از Profiler استفاده کنید: 'app' را به عنوان debuggable (complete data) اجرا کنید ). هنگام dump کردن heap، ممکن است مقدار حافظه جاوا به طور موقت افزایش یابد. این طبیعی است زیرا heap dump در همان فرآیند برنامه شما اتفاق می‌افتد و برای جمع‌آوری داده‌ها به مقداری حافظه نیاز دارد. پس از گرفتن heap dump، موارد زیر را مشاهده خواهید کرد:

نمای Heap Dump در اندروید استودیو پروفایلر.

لیست کلاس‌ها اطلاعات زیر را نشان می‌دهد:

  • تخصیص‌ها : تعداد تخصیص‌ها در هیپ.
  • اندازه بومی : کل مقدار حافظه بومی استفاده شده توسط این نوع شیء (به بایت). در اینجا حافظه‌ای را برای برخی از اشیاء اختصاص داده شده در جاوا مشاهده خواهید کرد زیرا اندروید از حافظه بومی برای برخی از کلاس‌های چارچوب، مانند Bitmap ، استفاده می‌کند.

  • اندازه کم عمق : کل مقدار حافظه جاوا که توسط این نوع شیء استفاده می‌شود (برحسب بایت).

  • حجم ذخیره‌شده : کل حجم حافظه‌ای که به دلیل وجود تمام نمونه‌های این کلاس ذخیره می‌شود (برحسب بایت).

از منوی heap برای فیلتر کردن به heap های خاص استفاده کنید:

  • App heap (پیش‌فرض) : هیپ اصلی که برنامه شما حافظه را روی آن اختصاص می‌دهد.
  • ایمیج هیپ : ایمیج بوت سیستم، شامل کلاس‌هایی که در طول زمان بوت از قبل بارگذاری می‌شوند. تخصیص‌ها در اینجا هرگز جابجا نمی‌شوند یا از بین نمی‌روند.
  • Zygote heap : هیپ کپی-هنگام-نوشتن که در آن فرآیند برنامه در سیستم اندروید از آن منشعب می‌شود.

برای انتخاب نحوه چیدمان تخصیص‌ها، از منوی کشویی «چیدمان» استفاده کنید:

  • مرتب‌سازی بر اساس کلاس (پیش‌فرض) : تمام تخصیص‌ها را بر اساس نام کلاس گروه‌بندی می‌کند.
  • مرتب‌سازی بر اساس بسته : تمام تخصیص‌ها را بر اساس نام بسته گروه‌بندی می‌کند.

از منوی کشویی class برای فیلتر کردن به گروه‌هایی از کلاس‌ها استفاده کنید:

  • همه کلاس‌ها (پیش‌فرض) : همه کلاس‌ها، شامل کلاس‌های کتابخانه‌ها و وابستگی‌ها را نشان می‌دهد.
  • نمایش نشت فعالیت/قطعه : کلاس‌هایی را نشان می‌دهد که باعث نشت حافظه می‌شوند.
  • نمایش کلاس‌های پروژه : فقط کلاس‌های تعریف‌شده توسط پروژه شما را نشان می‌دهد.

برای باز کردن پنجره نمونه (Instance) ، روی نام کلاس کلیک کنید. هر نمونه لیست شده شامل موارد زیر است:

  • عمق : کوتاه‌ترین تعداد گام‌ها از هر ریشه GC به نمونه انتخاب شده.
  • اندازه بومی : اندازه این نمونه در حافظه بومی. این ستون فقط برای اندروید ۷.۰ و بالاتر قابل مشاهده است.
  • اندازه کم عمق : اندازه این نمونه در حافظه جاوا.
  • اندازه حفظ‌شده : اندازه حافظه‌ای که این نمونه بر آن تسلط دارد (مطابق با درخت غالب )).

برای نمایش جزئیات نمونه ، شامل فیلدها و ارجاعات آن، روی یک نمونه کلیک کنید. انواع رایج فیلد و ارجاع، از نوع ساختاریافته هستند. ، آرایه‌ها و انواع داده‌های اولیه در جاوا. برای رفتن به نمونه یا خط مرتبط در کد منبع، روی یک فیلد یا مرجع کلیک راست کنید.

  • فیلدها : تمام فیلدهای موجود در این نمونه را نشان می‌دهد.
  • ارجاعات : هر ارجاع به شیء برجسته‌شده در برگه نمونه را نشان می‌دهد.
نماهای Instances ، Fields و References در پنجره ابزار Heap Dump.

نشت حافظه را پیدا کنید

برای فیلتر کردن سریع کلاس‌هایی که ممکن است با نشت حافظه مرتبط باشند، منوی کشویی کلاس را باز کنید و نمایش نشت فعالیت/قطعه را انتخاب کنید. اندروید استودیو کلاس‌هایی را نشان می‌دهد که فکر می‌کند نشان‌دهنده نشت حافظه برای نمونه‌های Activity و Fragment در برنامه شما هستند.

برای جستجوی دستی‌تر نشت حافظه، لیست کلاس‌ها و نمونه‌ها را مرور کنید تا اشیاء با اندازه نگهداری بزرگ (Retained Size) را پیدا کنید. نشت حافظه ناشی از هر یک از موارد زیر را جستجو کنید:

  • ارجاعات طولانی مدت به Activity یا Context که می‌توانند نمودار ترکیب Compose میزبانی شده را نشت دهند (مانند ComposeView و زیر-ترکیب‌پذیرهای آن).
  • نشت اشیاء حالت ترکیبی Jetpack ( MutableState )، نگهدارنده‌های حالت یا لامبداهایی که Context را در بر می‌گیرند.
  • فراموش کردن پاک کردن شنونده‌ها یا مشاهده‌کننده‌ها در بلوک onDispose از یک DisposableEffect .
  • کلاس‌های داخلی غیراستاتیک، مانند Runnable که می‌توانند یک نمونه Activity در خود نگه دارند.
  • حافظه‌های نهان (کش) که اشیاء را بیش از زمان لازم نگه می‌دارند.

وقتی نشتی حافظه احتمالی را پیدا کردید، از تب‌های Fields و References در Instance Details برای پرش به خط مورد نظر در نمونه یا کد منبع استفاده کنید.

فعال کردن نشت حافظه برای آزمایش

برای تجزیه و تحلیل میزان استفاده از حافظه، باید کد برنامه خود را تحت فشار قرار دهید و سعی کنید نشت حافظه را ایجاد کنید. یکی از راه‌های ایجاد نشت حافظه در برنامه شما این است که قبل از بررسی هیپ، اجازه دهید مدتی اجرا شود. نشت‌ها ممکن است به بالای تخصیص‌های هیپ برسند. با این حال، هرچه نشت کوچکتر باشد، برای مشاهده آن باید برنامه را مدت زمان بیشتری اجرا کنید.

همچنین می‌توانید به یکی از روش‌های زیر نشت حافظه را ایجاد کنید:

  • چندین بار دستگاه را در حالت‌های مختلف فعالیت از حالت عمودی به افقی و برعکس بچرخانید. چرخاندن دستگاه اغلب می‌تواند باعث نشت یک Activity (و در نتیجه درخت رابط کاربری Compose میزبان و درخت‌های وضعیت مرتبط) در برنامه شود، اگر برنامه شما ارجاعی به Activity یا Context در عملیات ناهمزمان یا دارندگان وضعیت داشته باشد.
  • بین برنامه خود و برنامه دیگری در حالت‌های مختلف فعالیت جابجا شوید. برای مثال، به صفحه اصلی بروید، سپس به برنامه خود برگردید.

خروجی گرفتن و وارد کردن ضبط هیپ دامپ

شما می‌توانید یک فایل heap dump را از تب Past Recordings در profiler استخراج و وارد کنید . اندروید استودیو فایل ضبط شده را به عنوان یک فایل .hprof ذخیره می‌کند.

روش دیگر، برای استفاده از یک تحلیلگر فایل .hprof متفاوت مانند jhat ، باید فایل .hprof را از فرمت اندروید به فرمت فایل .hprof جاوا SE تبدیل کنید. برای تبدیل فرمت فایل، از ابزار hprof-conv ارائه شده در دایرکتوری {android_sdk}/platform-tools/ استفاده کنید. دستور hprof-conv را با دو آرگومان اجرا کنید: نام فایل .hprof اصلی و مکانی که فایل .hprof تبدیل شده، شامل نام فایل .hprof جدید، در آن ذخیره می‌شود. برای مثال:

hprof-conv heap-original.hprof heap-converted.hprof

منابع اضافی