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

یک 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 ، استفاده می‌کند.

  • Shallow Size : Total amount of Java memory used by this object type (in bytes).

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

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

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

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

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

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

  • All classes (default) : Shows all classes, including those from libraries and dependencies.
  • نمایش نشت فعالیت/قطعه : کلاس‌هایی را نشان می‌دهد که باعث نشت حافظه می‌شوند.
  • نمایش کلاس‌های پروژه : فقط کلاس‌های تعریف‌شده توسط پروژه شما را نشان می‌دهد.

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

  • Depth : The shortest number of hops from any GC root to the selected instance.
  • Native Size : Size of this instance in native memory. This column is visible only for Android 7.0 and higher.
  • اندازه کم عمق : اندازه این نمونه در حافظه جاوا.
  • اندازه حفظ‌شده : اندازه حافظه‌ای که این نمونه بر آن تسلط دارد (مطابق با درخت غالب )).

Click an instance to show the Instance Details , including its Fields and References . Common field and reference types are structured types ، آرایه‌ها و انواع داده‌های اولیه in Java. Right-click on a field or reference to go to the associated instance or line in the source code.

  • فیلدها : تمام فیلدهای موجود در این نمونه را نشان می‌دهد.
  • ارجاعات : هر ارجاع به شیء برجسته‌شده در برگه نمونه را نشان می‌دهد.
The Instances , Fields , and References views in the Heap Dump tool window.

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

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

To look for memory leaks more manually, browse the class and instance lists to find objects with large Retained Size . Look for memory leaks caused by any of the following:

  • ارجاعات طولانی مدت به Activity یا Context که می‌توانند نمودار ترکیب Compose میزبانی شده را نشت دهند (مانند ComposeView و زیر-ترکیب‌پذیرهای آن).
  • Leaking Jetpack Compose State objects ( MutableState ), state holders, or lambdas that capture Context .
  • فراموش کردن پاک کردن شنونده‌ها یا مشاهده‌کننده‌ها در بلوک onDispose از یک DisposableEffect .
  • Non-static inner classes, such as a Runnable , that can hold an Activity instance.
  • حافظه‌های نهان (کش) که اشیاء را بیش از زمان لازم نگه می‌دارند.

When you find potential memory leaks, use the Fields and References tabs in Instance Details to jump to the instance or source code line of interest.

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

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

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

  • چندین بار دستگاه را در حالت‌های مختلف فعالیت از حالت عمودی به افقی و برعکس بچرخانید. چرخاندن دستگاه اغلب می‌تواند باعث نشت یک Activity (و در نتیجه درخت رابط کاربری Compose میزبان و درخت‌های وضعیت مرتبط) در برنامه شود، اگر برنامه شما ارجاعی به Activity یا Context در عملیات ناهمزمان یا دارندگان وضعیت داشته باشد.
  • Switch between your app and another app while in different activity states. For example, navigate to the home screen, then return to your app.

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

You can export and import a heap dump file from the Past Recordings tab in the profiler. Android Studio saves the recording as an .hprof file.

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

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

منابع اضافی