فرایند مخفی (lmkd) که برنامهها را بهدلیل کمبود حافظه در Android میبندد، وضعیت حافظه سیستم Android درحال اجرا را پایش میکند و با بستن فرایندهای غیرضروری به فشار زیاد روی حافظه واکنش نشان میدهد تا عملکرد سیستم را در سطح قابلقبول حفظ کند.
درباره فشار حافظه
سیستم Android که چندین فرایند را بهطور موازی اجرا میکند ممکن است با شرایطی مواجه شود که حافظه سیستم تمام شده باشد و فرایندهایی که به حافظه بیشتری نیاز دارند با تأخیرهای قابلتوجهی مواجه شوند. فشار حافظه، وضعیتی که در آن سیستم با کمبود حافظه مواجه میشود، باعث میشود Android با محدود کردن یا بستن فرایندهای غیرمهم، درخواست از فرایندها برای آزاد کردن منابع غیرحیاتی ذخیرهشده در حافظه نهان، و غیره، حافظه را آزاد کند (برای کاهش فشار).
در گذشته، Android فشار حافظه سیستم را بااستفاده از درایور «بستن ناشی از کمبود حافظه» (LMK) در هسته نظارت میکرد، مکانیزمی سخت که به مقادیر کدگذاریشده وابسته است. از هسته ۴.۱۲، درایور LMK از هسته بالادستی برداشته شده است و فضای کاربر lmkd وظایف نظارت بر حافظه و بستن فرایند را انجام میدهد.
اطلاعات توقف فشار
Android 10 و نسخههای بالاتر از حالت جدید lmkd پشتیبانی میکنند که از پایشگرهای اطلاعات توقف فشار هسته (PSI) برای تشخیص فشار حافظه استفاده میکند. مجموعه وصله PSI در هسته بالادستی (به هستههای ۴.۹ و ۴.۱۴ منتقل شده است) مدت زمانی را که تکالیف بهدلیل کمبود حافظه بهتأخیر میافتند اندازهگیری میکند. ازآنجاییکه این تأخیرها مستقیماً بر تجربه کاربری تأثیر میگذارند،
سنجه مناسبی برای تعیین شدت فشار روی حافظه هستند. هسته بالادستی همچنین شامل مانیتورهای PSI است که به فرایندهای فضای کاربری ممتاز (مانند lmkd) اجازه میدهد آستانههایی را برای این تأخیرها مشخص کنند و درصورت نقض آستانه، در رویدادهای هسته مشترک شوند.
نظارتهای PSI درمقابل سیگنالهای vmpressure
چون سیگنالهای vmpressure (که توسط هسته برای تشخیص فشار حافظه تولید میشود و توسط lmkd استفاده میشود) اغلب شامل موارد مثبت کاذب متعددی است، lmkd باید فیلتر کردن را انجام دهد تا مشخص کند آیا حافظه تحت فشار واقعی است یا نه.
این امر منجر به lmkd بیدار شدن غیرضروری و استفاده از منابع محاسباتی اضافی میشود. استفاده از PSI باعث میشود فشار حافظه با دقت بیشتری تشخیص داده شود و سربار فیلتر کردن به حداقل برسد.
استفاده از پایشگرهای PSI
برای استفاده از مانیتورهای PSI بهجای رویدادهای vmpressure،
ویژگی ro.lmk.use_psi را پیکربندی کنید. پیشفرض true است، که باعث میشود پایشگرهای PSI سازوکار پیشفرض تشخیص فشار حافظه برای lmkd باشند. چون پایشگرهای PSI
به پشتیبانی هسته نیاز دارند، هسته باید شامل وصلههای backport PSI باشد و
با فعال بودن پشتیبانی PSI (CONFIG_PSI=y) کامپایل شود.
معایب درایور LMK درون هسته
Android درایور LMK را بهدلیل چند مشکل منسوخ میکند، ازجمله:
- دستگاههای با حافظه دسترسی تصادفی کم باید بهصورت تهاجمی تنظیم میشدند و حتی در این صورت نیز در حجمهای کاری با صفحه فعال پشتیبانگیریشده با فایل بزرگ عملکرد ضعیفی داشتند. عملکرد ضعیف منجر به شکست و عدم کشتن شد.
- درایور هسته LMK به محدودیتهای حافظه آزاد متکی بود و هیچ مقیاسبندیای براساس فشار حافظه نداشت.
- بهدلیل انعطافناپذیری طراحی، شرکا اغلب درایور را سفارشیسازی میکردند تا در دستگاههایشان کار کند.
- گرداننده LMK به میانای برنامهسازی کاربردی slab shrinker متصل شده بود که برای عملیات سنگین مانند جستجوی اهداف و ازبین بردن آنها طراحی نشده بود و این امر فرایند
vmscanرا کند میکرد.
Userspace lmkd
lmkd فضای کاربر همان عملکرد درایور درون هسته را پیادهسازی میکند
اما از سازوکارهای هسته موجود برای شناسایی و تخمین فشار حافظه استفاده میکند. چنین سازوکارهایی شامل استفاده از رویدادهای vmpressure تولیدشده توسط هسته یا پایشگرهای اطلاعات توقف تحت فشار (PSI) برای دریافت اعلان درباره سطوح فشار حافظه، و استفاده از ویژگیهای گروه کنترل حافظه برای محدود کردن منابع حافظه اختصاصیافته به هر فرایند براساس اهمیت فرایند است.
استفاده از lmkd فضای کاربر در Android 10
در Android 9 و نسخههای بالاتر، اگر
دراور LMK درون هسته شناسایی نشود، فضای کاربر lmkd فعال میشود. ازآنجاییکه فضای کاربر lmkd
به پشتیبانی هسته برای گروههای کنترل حافظه نیاز دارد، هسته باید با تنظیمات پیکربندی زیر کامپایل شود:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
استراتژیهای کشتن
فضای کاربر lmkd از استراتژیهای کشتن براساس رویدادهای vmpressure یا پایشهای PSI، شدت آنها، و نشانهای دیگر مثل استفاده از مبادله پشتیبانی میکند. استراتژیهای بستن
برنامهها در دستگاههای با حافظه کم و دستگاههای با عملکرد بالا متفاوت است:
- در دستگاههای دارای حافظه کم، سیستم باید فشار حافظه بالاتر را بهعنوان حالت عملکرد عادی تحمل کند.
- در دستگاههای با عملکرد بالا، فشار حافظه باید بهعنوان وضعیتی غیرعادی درنظر گرفته شود و قبلاز اینکه بر عملکرد کلی تأثیر بگذارد، برطرف شود.
میتوانید راهبرد کشتن را بااستفاده از دارایی ro.config.low_ram پیکربندی کنید.
فضای کاربر lmkd همچنین از حالت قدیمیای پشتیبانی میکند که در آن تصمیمات کشتن را بااستفاده از همان استراتژیهای درایور LMK درون هسته (یعنی آستانههای حافظه آزاد و حافظه نهان فایل) میگیرد. برای فعال کردن حالت قدیمی،
خصوصیت ro.lmk.use_minfree_levels را روی true تنظیم کنید.
پیکربندی lmkd
lmkd را برای دستگاهی خاص بااستفاده از ویژگیهای زیر پیکربندی کنید.
| دارایی | استفاده کردن | پیشفرض |
|---|---|---|
ro.config.low_ram
|
مشخص کنید دستگاه دارای RAM کم است یا عملکرد بالایی دارد. | false
|
ro.lmk.use_psi |
از پایشگرهای PSI (بهجای رویدادهای vmpressure) استفاده کنید. |
true |
ro.lmk.use_minfree_levels
|
از آستانههای حافظه آزاد و حافظه نهان فایل برای تصمیمگیری درباره بستن فرایندها استفاده کنید (یعنی عملکرد درایور LMK درون هسته را مطابقت دهید). | false
|
ro.lmk.low
|
حداقل امتیاز oom_adj برای فرایندهای واجدشرایط برای بسته شدن در سطح پایین vmpressure.
|
1001(غیرفعال) |
ro.lmk.medium
|
حداقل امتیاز oom_adj برای فرایندهای واجدشرایط برای
متوقف شدن در سطح متوسط vmpressure.
|
800(سرویسهای حافظه نهان یا غیرضروری) |
ro.lmk.critical
|
حداقل امتیاز oom_adj برای فرایندهای واجدشرایط برای
متوقف شدن در سطح بحرانی vmpressure.
|
0(هر فرایندی) |
ro.lmk.critical_upgrade
|
ارتقا به سطح بحرانی را فعال کنید. | false
|
ro.lmk.upgrade_pressure
|
حداکثر mem_pressure که در آن سطح ارتقا مییابد
زیرا سیستم بیشازحد درحال جابهجایی است.
|
100(غیرفعال) |
ro.lmk.downgrade_pressure
|
حداقل mem_pressure که در آن رویداد vmpressure نادیده گرفته میشود زیرا هنوز حافظه آزاد کافی دردسترس است.
|
100(غیرفعال) |
ro.lmk.kill_heaviest_task
|
سنگینترین تکلیف واجدشرایط را متوقف کن (بهترین تصمیم) درمقایسه با هر تکلیف واجدشرایط (تصمیم سریع). | false
|
ro.lmk.kill_timeout_ms
|
مدتزمان برحسب میلیثانیه پساز توقف اجباری که در آن توقف اجباری دیگری انجام نخواهد شد. | 0(غیرفعال) |
ro.lmk.debug
|
گزارشهای اشکالزدایی lmkd را فعال کنید.
|
false
|
نمونه پیکربندی دستگاه:
PRODUCT_PROPERTY_OVERRIDES += \
ro.lmk.low=1001 \
ro.lmk.medium=800 \
ro.lmk.critical=0 \
ro.lmk.critical_upgrade=false \
ro.lmk.upgrade_pressure=100 \
ro.lmk.downgrade_pressure=100 \
ro.lmk.kill_heaviest_task=true
کاربرفضای lmkd در Android 11
Android 11 با معرفی استراتژی جدید
کشتن، lmkd را بهبود میبخشد. استراتژی بستن از سازوکار PSI برای تشخیص فشار حافظه استفاده میکند که در Android 10 معرفی شده است. lmkd در Android 11 سطوح استفاده از منبع حافظه و
جابهجایی دادهها در حافظه را درنظر میگیرد تا از کمبود حافظه و افت عملکرد جلوگیری کند.
این استراتژی کشتن جایگزین استراتژیهای قبلی میشود و میتواند در هر دو دستگاه
با عملکرد بالا و با حافظه دسترسی تصادفی پایین (Android Go) استفاده شود.
الزامات هسته
برای دستگاههای Android 11، lmkd به ویژگیهای هسته زیر نیاز دارد:
- وصلههای PSI را اضافه کنید و PSI را فعال کنید (نسخههای قدیمی در هستههای مشترک Android 4.9، 4.14، و 4.19 دردسترس است).
- وصلههای پشتیبانی PIDFD را اضافه کنید (پورتهای پشتیبان در هستههای مشترک Android ۴.۹، ۴.۱۴، و ۴.۱۹ دردسترس است).
- برای دستگاههای با حافظه دسترسی تصادفی کم، cgroups حافظه را اضافه کنید.
هسته باید با تنظیمات پیکربندی زیر کامپایل شود:
CONFIG_PSI=y
پیکربندی lmkd در Android 11
استراتژی کشتن حافظه در Android 11 از پیچهای تنظیم و پیشفرضهای فهرستشده در زیر پشتیبانی میکند. این ویژگیها در دستگاههای با عملکرد بالا و حافظه دسترسی تصادفی پایین کار میکند.
| دارایی | استفاده کردن | پیشفرض | |
|---|---|---|---|
| عملکرد بالا | حافظه دسترسی تصادفی کم | ||
ro.lmk.psi_partial_stall_ms |
آستانه توقف جزئی PSI، برحسب میلیثانیه، برای راهاندازی اعلان حافظه کم. اگر دستگاه اعلانهای فشار حافظه را خیلی دیر دریافت میکند، این مقدار را کاهش دهید تا اعلانها زودتر راهاندازی شوند. اگر اعلانهای فشار حافظه بهطور غیرضروری راهاندازی میشوند، این مقدار را افزایش دهید تا دستگاه به صدا حساسیت کمتری نشان دهد. | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
آستانه توقف کامل PSI، برحسب میلیثانیه، برای راهاندازی اعلانهای حافظه حیاتی. اگر دستگاه اعلانهای فشار بحرانی حافظه را خیلی دیر دریافت میکند، این مقدار را کاهش دهید تا اعلانها زودتر راهاندازی شوند. اگر اعلانهای فشار حافظه بحرانی بهطور غیرضروری راهاندازی میشوند، این مقدار را افزایش دهید تا دستگاه به نویز حساسیت کمتری نشان دهد. | 700 |
|
ro.lmk.thrashing_limit |
حداکثر مقدار خطاهای کاری بهعنوان درصدی از کل اندازه حافظه نهان صفحه پشتیبان فایل. اگر مقدار Workingset refaults بالاتر از این مقدار باشد، یعنی سیستم درحال کوبیدن حافظه پنهان صفحه است. اگر عملکرد دستگاه درطول فشار حافظه تحتتأثیر قرار میگیرد، مقدار را کاهش دهید تا تخریب محدود شود. اگر عملکرد دستگاه بهدلیل دلیل غیرضروری برای کوبیدن متوقف شد، مقدار را افزایش دهید تا کوبیدن بیشتری مجاز شود. | 100 |
30 |
ro.lmk.thrashing_limit_decay |
آستانه تخریب که بهصورت درصد از آستانه اصلی بیان میشود برای کاهش آستانه زمانی استفاده میشود که سیستم حتی پساز کشتن نیز بهبود نمییابد. اگر کوبش پیوسته باعث کشتارهای غیرضروری میشود، مقدار را کاهش دهید. اگر پاسخ به کوبش پیوسته پساز کشتن بسیار کند است، مقدار را افزایش دهید. | 10 |
50 |
ro.lmk.swap_util_max |
حداکثر مقدار حافظه مبادلهشده بهصورت درصد از کل حافظه قابلمبادله. وقتی حافظه مبادلهشده از این حد فراتر میرود، یعنی سیستم بیشتر حافظه قابلمبادله خود را مبادله کرده است و همچنان تحت فشار است.
این وضعیت زمانی رخ میدهد که تخصیصهای غیرقابل تعویض فشار حافظه ایجاد میکنند که با تعویض نمیتوان آن را کاهش داد زیرا بیشتر حافظه قابل تعویض قبلاً تعویض شده است. مقدار پیشفرض ۱۰۰ است که عملاً این بررسی را غیرفعال میکند. اگر عملکرد دستگاه درطول فشار حافظه تحتتأثیر قرار میگیرد، درحالیکه استفاده از فضای مبادله بالا است و سطح فضای مبادله آزاد به ro.lmk.swap_free_low_percentage کاهش نمییابد، مقدار را کاهش دهید تا استفاده از فضای مبادله محدود شود. |
100 |
100 |
دکمههای تنظیم قدیمی زیر نیز با استراتژی جدید توقف کار میکنند.
| دارایی | استفاده کردن | پیشفرض | |
|---|---|---|---|
| عملکرد بالا | حافظه دسترسی تصادفی کم | ||
ro.lmk.swap_free_low_percentage |
سطح مبادله آزاد بهعنوان درصدی از کل فضای مبادله. `lmkd` از این مقدار بهعنوان آستانهای برای زمانی استفاده میکند که سیستم را بهعنوان فضای مبادله گرسنه درنظر بگیرد. اگر `lmkd` درحالیکه فضای زیادی در swap وجود دارد، درصد را کاهش دهید. اگر کشتنهای `lmkd` خیلی دیر اتفاق میافتد و باعث میشود کشتنهای OOM اتفاق بیفتد، درصد را افزایش دهید. | 20 |
10 |
ro.lmk.debug |
با این کار، گزارشهای اشکالزدایی `lmkd` فعال میشود. اشکالزدایی را درحین تنظیم فعال کنید. | false |
|