پلتفرم اندروید با این فرض کار میکند که حافظه آزاد، حافظه هدر رفته است. این پلتفرم سعی میکند همیشه از تمام حافظه موجود استفاده کند. به عنوان مثال، سیستم برنامهها را پس از بسته شدن در حافظه نگه میدارد تا کاربر بتواند به سرعت به آنها بازگردد. به همین دلیل، دستگاههای اندروید اغلب با حافظه آزاد بسیار کمی اجرا میشوند. مدیریت حافظه برای تخصیص صحیح حافظه بین فرآیندهای مهم سیستم و بسیاری از برنامههای کاربر حیاتی است.
این صفحه اصول اولیه نحوه تخصیص حافظه اندروید برای سیستم و برنامههای کاربر را مورد بحث قرار میدهد. همچنین توضیح میدهد که چگونه سیستم عامل به موقعیتهای کمبود حافظه واکنش نشان میدهد.
انواع حافظه
دستگاههای اندروید شامل سه نوع حافظه مختلف هستند: RAM، zRAM و حافظه ذخیرهسازی. توجه داشته باشید که هم CPU و هم GPU به یک RAM دسترسی دارند.
شکل ۱. انواع حافظه - RAM، zRAM و فضای ذخیرهسازی
رم سریعترین نوع حافظه است، اما معمولاً از نظر اندازه محدود است. دستگاههای رده بالا معمولاً بیشترین مقدار رم را دارند.
zRAM یک پارتیشن از RAM است که برای فضای swap استفاده میشود. همه چیز هنگام قرار گرفتن در zRAM فشرده میشود و سپس هنگام کپی شدن از zRAM از حالت فشرده خارج میشود. با انتقال صفحات به zRAM یا خارج شدن از آن، اندازه این بخش از RAM افزایش یا کاهش مییابد. تولیدکنندگان دستگاه میتوانند حداکثر اندازه را تعیین کنند.
فضای ذخیرهسازی شامل تمام دادههای پایدار مانند سیستم فایل و کد شیء گنجانده شده برای همه برنامهها، کتابخانهها و پلتفرم است. فضای ذخیرهسازی ظرفیت بسیار بیشتری نسبت به دو نوع حافظه دیگر دارد. در اندروید، از فضای ذخیرهسازی برای فضای swap مانند سایر پیادهسازیهای لینوکس استفاده نمیشود، زیرا نوشتن مکرر میتواند باعث فرسودگی این حافظه و کاهش عمر رسانه ذخیرهسازی شود.
صفحات حافظه
رم به صفحات (pages) تقسیم میشود. معمولاً هر صفحه ۴ کیلوبایت حافظه دارد.
صفحات یا آزاد هستند یا استفاده شده . صفحات آزاد، رم استفاده نشده هستند. صفحات استفاده شده، رمی هستند که سیستم به طور فعال از آن استفاده میکند و به دستههای زیر گروهبندی میشوند:
- حافظه پنهان (Cached): حافظهای که توسط یک فایل در حافظه پشتیبانی میشود (برای مثال، کد یا فایلهای نگاشتشده در حافظه). دو نوع حافظه پنهان وجود دارد:
- خصوصی: متعلق به یک فرآیند است و به اشتراک گذاشته نمیشود
- پاکسازی: کپی اصلاحنشدهی یک فایل در حافظه، که میتواند توسط
kswapdحذف شود تا حافظهی آزاد افزایش یابد. - کثیف: کپی اصلاحشدهی فایل روی حافظه؛ میتواند توسط
kswapdبه zRAM منتقل یا فشرده شود تا حافظهی آزاد افزایش یابد.
- پاکسازی: کپی اصلاحنشدهی یک فایل در حافظه، که میتواند توسط
- مشترک: توسط چندین فرآیند استفاده میشود
- خصوصی: متعلق به یک فرآیند است و به اشتراک گذاشته نمیشود
- ناشناس: حافظهای که توسط فایلی در فضای ذخیرهسازی پشتیبانی نمیشود (برای مثال، توسط
mmap()با پرچمMAP_ANONYMOUSاختصاص داده شده است)- کثیف: میتواند توسط
kswapdدر zRAM جابجا/فشرده شود تا حافظه آزاد افزایش یابد.
- کثیف: میتواند توسط
نسبت صفحات آزاد و استفاده شده با گذشت زمان تغییر میکند، زیرا سیستم به طور فعال RAM را مدیریت میکند. مفاهیم معرفی شده در این بخش، کلید مدیریت موقعیتهای کمبود حافظه هستند. بخش بعدی این سند آنها را با جزئیات بیشتری توضیح میدهد.
مدیریت حافظه کم
اندروید دو مکانیسم اصلی برای مقابله با شرایط کمبود حافظه دارد: دیمن تعویض هسته و قاتل کمبود حافظه.
دیمن تعویض هسته
دیمن سواپ هسته ( kswapd ) بخشی از هسته لینوکس است و حافظه استفاده شده را به حافظه آزاد تبدیل میکند. این دیمن زمانی فعال میشود که حافظه آزاد دستگاه کم شود. هسته لینوکس آستانههای حافظه آزاد کم و زیاد را حفظ میکند. وقتی حافظه آزاد از آستانه کم پایینتر میآید، kswapd شروع به بازپسگیری حافظه میکند. هنگامی که حافظه آزاد به آستانه زیاد میرسد، kswapd بازپسگیری حافظه را متوقف میکند.
kswapd میتواند با حذف صفحات پاک، آنها را بازیابی کند، زیرا این صفحات توسط حافظه پشتیبانی میشوند و تغییر نکردهاند. اگر فرآیندی سعی کند به یک صفحه پاک که حذف شده است، آدرسدهی کند، سیستم صفحه را از حافظه به RAM کپی میکند. این عملیات به عنوان صفحهبندی تقاضا شناخته میشود.
شکل ۲. صفحه پاکشده، با پشتیبانی ذخیرهسازی، حذف شده
kswapd میتواند صفحات کثیف خصوصی و صفحات کثیف ناشناس ذخیره شده در حافظه پنهان را به zRAM منتقل کند، جایی که فشرده میشوند. انجام این کار حافظه موجود در RAM (صفحات آزاد) را آزاد میکند. اگر فرآیندی سعی کند به یک صفحه کثیف در zRAM دست بزند، صفحه از حالت فشرده خارج شده و دوباره به RAM منتقل میشود. اگر فرآیند مرتبط با یک صفحه فشرده شده از بین برود، صفحه از zRAM حذف میشود.
اگر مقدار حافظه آزاد از یک آستانه مشخص کمتر شود، سیستم شروع به از بین بردن فرآیندها میکند.
شکل ۳. صفحهی کثیف به zRAM منتقل و فشردهسازی شد
قاتل کم حافظه
بسیاری از مواقع، kswapd نمیتواند حافظه کافی برای سیستم را آزاد کند. در این حالت، سیستم onTrimMemory() برای اطلاع دادن به یک برنامه مبنی بر کمبود حافظه و کاهش تخصیص آن استفاده میکند. اگر این کافی نباشد، هسته شروع به از بین بردن فرآیندها برای آزاد کردن حافظه میکند. برای انجام این کار از low-memory killer (LMK) استفاده میکند.
برای تصمیمگیری در مورد اینکه کدام فرآیند را از بین ببرد، LMK از امتیاز "خارج از حافظه" به نام oom_adj_score برای اولویتبندی فرآیندهای در حال اجرا استفاده میکند. فرآیندهایی که امتیاز بالایی دارند ابتدا از بین میروند. برنامههای پسزمینه اولین فرآیندهایی هستند که از بین میروند و فرآیندهای سیستمی آخرین فرآیندهایی هستند که از بین میروند. جدول زیر دستههای امتیازدهی LMK را از بالا به پایین فهرست میکند. مواردی که در دسته بالاترین امتیاز، در ردیف اول، قرار دارند، ابتدا از بین میروند:
شکل ۴. پردازشهای اندروید، با امتیازهای بالا در بالا و امتیازهای پایین در پایین
اینها توضیحاتی برای دستههای مختلف در جدول بالا هستند:
برنامههای پسزمینه: برنامههایی که قبلاً اجرا میشدند و در حال حاضر فعال نیستند. LMK ابتدا برنامههای پسزمینه را از بین میبرد و از برنامهای که بالاترین
oom_adj_scoreرا دارد، شروع میکند.برنامه قبلی: برنامهای که اخیراً در پسزمینه استفاده شده است. برنامه قبلی اولویت بالاتری (امتیاز پایینتری) نسبت به برنامههای پسزمینه دارد، زیرا احتمال اینکه کاربر به آن سوئیچ کند، بیشتر از یکی از برنامههای پسزمینه است.
برنامهی خانه: این برنامهی لانچر است. با غیرفعال کردن آن، تصویر پسزمینه ناپدید میشود.
سرویسها: سرویسها توسط برنامهها آغاز میشوند و ممکن است شامل همگامسازی یا آپلود در فضای ابری باشند.
برنامههای قابل درک: برنامههای غیر پیشزمینه که به نوعی برای کاربر قابل درک هستند، مانند اجرای یک فرآیند جستجو که یک رابط کاربری کوچک را نمایش میدهد یا گوش دادن به موسیقی.
برنامهی پیشزمینه: برنامهای که در حال حاضر در حال استفاده است. غیرفعال کردن برنامهی پیشزمینه مانند از کار افتادن برنامه به نظر میرسد که ممکن است به کاربر نشان دهد مشکلی در دستگاه وجود دارد.
خدمات پایدار (Persistent): این خدمات، خدمات اصلی دستگاه هستند، مانند تلفن و وایفای.
سیستم: فرآیندهای سیستم. با بسته شدن این فرآیندها، ممکن است به نظر برسد که تلفن مجدداً راهاندازی میشود.
بومی: فرآیندهای بسیار سطح پایینی که توسط سیستم استفاده میشوند (برای مثال،
kswapd).
تولیدکنندگان دستگاه میتوانند رفتار LMK را تغییر دهند.
محاسبه میزان حافظه اشغال شده
هسته تمام صفحات حافظه در سیستم را ردیابی میکند.
شکل ۵. صفحات مورد استفاده توسط فرآیندهای مختلف
هنگام تعیین میزان حافظه مورد استفاده توسط یک برنامه، سیستم باید صفحات مشترک را در نظر بگیرد. برنامههایی که به یک سرویس یا کتابخانه دسترسی دارند، صفحات حافظه را به اشتراک میگذارند. به عنوان مثال، سرویسهای گوگل پلی و یک برنامه بازی ممکن است یک سرویس موقعیت مکانی را به اشتراک بگذارند. این امر تعیین میزان حافظه متعلق به سرویس به طور کلی در مقابل هر برنامه را دشوار میکند.
شکل ۶. صفحات به اشتراک گذاشته شده توسط دو برنامه (وسط)
برای تعیین میزان حافظه اشغال شده توسط یک برنامه، میتوان از هر یک از معیارهای زیر استفاده کرد:
- اندازه مجموعه ساکن (RSS): تعداد صفحات مشترک و غیر مشترک مورد استفاده برنامه
- اندازه مجموعه متناسب (PSS): تعداد صفحات غیر مشترک مورد استفاده توسط برنامه و توزیع یکنواخت صفحات مشترک (برای مثال، اگر سه فرآیند ۳ مگابایت را به اشتراک میگذارند، هر فرآیند ۱ مگابایت در PSS دریافت میکند)
- اندازه مجموعه منحصر به فرد (USS): تعداد صفحات غیر مشترک مورد استفاده توسط برنامه (صفحات مشترک شامل نمیشوند)
PSS برای سیستم عامل زمانی مفید است که میخواهد بداند چقدر حافظه توسط همه فرآیندها استفاده میشود، زیرا صفحات چندین بار شمارش نمیشوند. محاسبه PSS زمان زیادی میبرد زیرا سیستم باید تعیین کند کدام صفحات و توسط چند فرآیند به اشتراک گذاشته شدهاند. RSS بین صفحات مشترک و غیر مشترک تمایزی قائل نمیشود (که محاسبه آن را سریعتر میکند) و برای ردیابی تغییرات در تخصیص حافظه بهتر است.
منابع اضافی
- مروری بر مدیریت حافظه
- فرآیندها و چرخه حیات برنامه
- درک میزان استفاده از حافظه اندروید - ارائه Google I/O
- حافظه و بازیهای اندروید - ارائه گوگل I/O
- دیمن قاتل حافظه کم اندروید
برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- زمان شروع برنامه