فرآیند حذف حافظه کم اندروید ( lmkd ) وضعیت حافظه یک سیستم اندروید در حال اجرا را رصد میکند و با از بین بردن فرآیندهای کماهمیتتر، به فشار بالای حافظه واکنش نشان میدهد تا عملکرد سیستم در سطوح قابل قبول حفظ شود.
درباره فشار حافظه
یک سیستم اندروید که چندین فرآیند را به صورت موازی اجرا میکند، ممکن است با موقعیتهایی مواجه شود که حافظه سیستم تمام شود و فرآیندهایی که به حافظه بیشتری نیاز دارند، تأخیرهای قابل توجهی را تجربه کنند. فشار حافظه ، حالتی که سیستم با کمبود حافظه مواجه است، اندروید را ملزم میکند تا با محدود کردن یا از بین بردن فرآیندهای بیاهمیت، درخواست آزادسازی منابع ذخیره شده غیرحیاتی توسط فرآیندها و غیره، حافظه را آزاد کند (تا فشار را کاهش دهد).
از لحاظ تاریخی، اندروید فشار حافظه سیستم را با استفاده از یک درایور درون هسته ایِ حذف کننده حافظه کم (LMK) نظارت میکرد، یک مکانیزم سفت و سخت که به مقادیر کدگذاری شده وابسته است. از هسته ۴.۱۲، درایور LMK از هسته بالادستی حذف شده و lmkd فضای کاربری وظایف نظارت بر حافظه و حذف فرآیند را انجام میدهد.
اطلاعات مربوط به واماندگی فشار
اندروید ۱۰ و بالاتر از یک حالت جدید lmkd پشتیبانی میکنند که از مانیتورهای اطلاعات توقف فشار هسته (PSI) برای تشخیص فشار حافظه استفاده میکند. مجموعه وصلههای PSI در هسته بالادستی (که به هستههای ۴.۹ و ۴.۱۴ بکپورت شده است) میزان زمانی را که وظایف به دلیل کمبود حافظه به تأخیر میافتند، اندازهگیری میکند. از آنجایی که این تأخیرها مستقیماً بر تجربه کاربر تأثیر میگذارند، معیار مناسبی برای تعیین شدت فشار حافظه هستند. هسته بالادستی همچنین شامل مانیتورهای PSI است که به فرآیندهای فضای کاربری ممتاز (مانند lmkd ) اجازه میدهد آستانههایی را برای این تأخیرها مشخص کنند و در صورت نقض آستانه، در رویدادهای هسته مشترک شوند.
مانیتورهای PSI در مقابل سیگنالهای فشار vm
از آنجا که سیگنالهای vmpressure (که توسط هسته برای تشخیص فشار حافظه تولید میشوند و توسط lmkd استفاده میشوند) اغلب شامل موارد مثبت کاذب متعددی هستند، lmkd باید فیلترینگ را انجام دهد تا مشخص شود که آیا حافظه تحت فشار واقعی است یا خیر. این امر منجر به بیدار شدنهای غیرضروری lmkd و استفاده از منابع محاسباتی اضافی میشود. استفاده از مانیتورهای PSI منجر به تشخیص دقیقتر فشار حافظه و به حداقل رساندن سربار فیلترینگ میشود.
از مانیتورهای PSI استفاده کنید
برای استفاده از مانیتورهای PSI به جای رویدادهای vmpressure ، ویژگی ro.lmk.use_psi را پیکربندی کنید. مقدار پیشفرض true است و مانیتورهای PSI را به مکانیزم پیشفرض تشخیص فشار حافظه برای lmkd تبدیل میکند. از آنجا که مانیتورهای PSI به پشتیبانی هسته نیاز دارند، هسته باید شامل پچهای پشتیبان PSI باشد و با پشتیبانی فعال از PSI کامپایل شود ( CONFIG_PSI=y ).
معایب درایور LMK درون هسته
اندروید به دلیل تعدادی از مشکلات، درایور LMK را منسوخ میکند، از جمله:
- دستگاههای با رم کم باید به شدت تنظیم میشدند، و حتی در آن صورت هم در بارهای کاری با حافظه نهان فعال فایل بزرگ، عملکرد ضعیفی داشتند. عملکرد ضعیف منجر به کند شدن و عدم موفقیت میشد.
- درایور هسته LMK بر محدودیتهای حافظه آزاد تکیه داشت و هیچ مقیاسبندی بر اساس فشار حافظه نداشت.
- به دلیل سختی طراحی، شرکا اغلب درایور را طوری سفارشی میکردند که روی دستگاههایشان کار کند.
- درایور LMK به API مربوط به جمعکنندهی قطعات (slab shrinker) متصل میشد، که برای عملیات سنگین مانند جستجوی اهداف و از بین بردن آنها طراحی نشده بود، و این امر روند
vmscanکند میکرد.
فضای کاربری lmkd
فضای کاربری lmkd همان عملکرد درایور درون هسته را پیادهسازی میکند، اما از مکانیسمهای موجود هسته برای تشخیص و تخمین فشار حافظه استفاده میکند. چنین مکانیسمهایی شامل استفاده از رویدادهای vmpressure تولید شده توسط هسته یا مانیتورهای اطلاعات توقف فشار (PSI) برای دریافت اعلانها در مورد سطوح فشار حافظه و استفاده از ویژگیهای گروه حافظه برای محدود کردن منابع حافظه اختصاص داده شده به هر فرآیند بر اساس اهمیت فرآیند است.
استفاده از فضای کاربری lmkd در اندروید ۱۰
در اندروید ۹ و بالاتر، اگر درایور LMK درون هسته شناسایی نشود، userspace lmkd فعال میشود. از آنجا که userspace lmkd به پشتیبانی هسته برای گروههای حافظه نیاز دارد، هسته باید با تنظیمات پیکربندی زیر کامپایل شود:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
استراتژیهای کشتن
فضای کاربری lmkd از استراتژیهای kill بر اساس رویدادهای vmpressure یا مانیتورهای PSI، شدت آنها و سایر نکات مانند استفاده از swap پشتیبانی میکند. استراتژیهای kill بین دستگاههای کمحافظه و با کارایی بالا متفاوت است:
- در دستگاههای با حافظه کم، سیستم باید فشار حافظه بالاتر را به عنوان یک حالت عملیاتی عادی تحمل کند.
- در دستگاههای با کارایی بالا، فشار حافظه باید به عنوان یک وضعیت غیرعادی در نظر گرفته شود و قبل از اینکه بر عملکرد کلی تأثیر بگذارد، برطرف شود.
شما میتوانید استراتژی kill را با استفاده از ویژگی ro.config.low_ram پیکربندی کنید.
فضای کاربری lmkd همچنین از حالت قدیمی (legacy mode) پشتیبانی میکند که در آن تصمیمات kill را با استفاده از همان استراتژیهای درایور LMK درون هسته (یعنی آستانههای آزادسازی حافظه و حافظه پنهان فایل) میگیرد. برای فعال کردن حالت قدیمی، ویژگی ro.lmk.use_minfree_levels را روی true تنظیم کنید.
پیکربندی lmkd
lmkd برای یک دستگاه خاص با استفاده از ویژگیهای زیر پیکربندی کنید.
| ملک | استفاده کنید | پیشفرض |
|---|---|---|
ro.config.low_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 بحرانی vm هستند. | 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 در اندروید ۱۱
اندروید ۱۱ با معرفی یک استراتژی جدید kill، lmkd را بهبود میبخشد. این استراتژی kill از مکانیزم PSI برای تشخیص فشار حافظه که در اندروید ۱۰ معرفی شده بود، استفاده میکند. lmkd در اندروید ۱۱، سطوح استفاده از منابع حافظه و thrashing را برای جلوگیری از گرسنگی حافظه و کاهش عملکرد در نظر میگیرد. این استراتژی kill جایگزین استراتژیهای قبلی شده و میتواند هم در دستگاههای با عملکرد بالا و هم در دستگاههای با رم پایین (Android Go) استفاده شود.
الزامات هسته
برای دستگاههای اندروید ۱۱، lmkd به ویژگیهای کرنل زیر نیاز دارد:
- وصلههای PSI را اضافه کنید و PSI را فعال کنید (پشتیبانگیریها در هستههای رایج اندروید ۴.۹، ۴.۱۴ و ۴.۱۹ موجود است).
- وصلههای پشتیبانی PIDFD (پشتیبانگیریهای موجود در هستههای رایج اندروید ۴.۹، ۴.۱۴ و ۴.۱۹) را لحاظ کنید.
- برای دستگاههای با رم کم، گروههای حافظه (cgroups) را نیز لحاظ کنید.
هسته باید با تنظیمات پیکربندی زیر کامپایل شود:
CONFIG_PSI=y
پیکربندی lmkd در اندروید ۱۱
استراتژی حذف حافظه در اندروید ۱۱ از دکمههای تنظیم و پیشفرضهای ذکر شده در زیر پشتیبانی میکند. این ویژگیها هم روی دستگاههای با کارایی بالا و هم روی دستگاههای با رم کم کار میکنند.
| ملک | استفاده کنید | پیشفرض | |
|---|---|---|---|
| عملکرد بالا | رم پایین | ||
ro.lmk.psi_partial_stall_ms | آستانهی توقف جزئی PSI، بر حسب میلیثانیه، برای فعال کردن اعلان کمبود حافظه. اگر دستگاه اعلانهای فشار حافظه را خیلی دیر دریافت میکند، این مقدار را کاهش دهید تا اعلانها زودتر فعال شوند. اگر اعلانهای فشار حافظه بیجهت فعال میشوند، این مقدار را افزایش دهید تا دستگاه نسبت به نویز حساسیت کمتری داشته باشد. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | آستانه کامل توقف PSI، بر حسب میلیثانیه، برای فعال کردن اعلانهای حیاتی حافظه. اگر دستگاه اعلانهای فشار حیاتی حافظه را خیلی دیر دریافت کند، این مقدار را کاهش دهید تا اعلانها زودتر فعال شوند. اگر اعلانهای فشار حیاتی حافظه بیجهت فعال شوند، این مقدار را افزایش دهید تا دستگاه نسبت به نویز حساسیت کمتری داشته باشد. | 700 | |
ro.lmk.thrashing_limit | حداکثر مقدار خطاهای workingset به عنوان درصدی از کل اندازه حافظه پنهان صفحه (pagecache) فایل پشتیبان. خطاهای Workingset بالاتر از این مقدار به این معنی است که سیستم در حال استفاده از حافظه پنهان صفحه (pagecache) خود است. اگر عملکرد دستگاه در حین فشار بر حافظه تحت تأثیر قرار گیرد، مقدار را کاهش دهید تا thrashing را محدود کنید. اگر عملکرد دستگاه به دلایل thrashing بیجهت از بین میرود، مقدار را افزایش دهید تا thrashing بیشتری مجاز باشد. | 100 | 30 |
ro.lmk.thrashing_limit_decay | کاهش آستانهی کوبش (thrashing threshold) که به صورت درصدی از آستانهی اصلی بیان میشود و برای کاهش آستانه در زمانی که سیستم حتی پس از kill بازیابی نمیشود، استفاده میشود. اگر کوبش مداوم باعث killهای غیرضروری میشود، مقدار را کاهش دهید. اگر پاسخ به کوبش مداوم پس از kill خیلی کند است، مقدار را افزایش دهید. | 10 | 50 |
ro.lmk.swap_util_max | حداکثر مقدار حافظهی تعویضشده به عنوان درصدی از کل حافظهی قابل تعویض. وقتی حافظهی تعویضشده از این حد بیشتر شود، به این معنی است که سیستم بیشتر حافظهی قابل تعویض خود را تعویض کرده و هنوز تحت فشار است. این میتواند زمانی اتفاق بیفتد که تخصیصهای غیرقابل تعویض، فشار حافظه ایجاد میکنند که با تعویض قابل کاهش نیست زیرا بیشتر حافظهی قابل تعویض از قبل تعویض شده است. مقدار پیشفرض ۱۰۰ است که عملاً این بررسی را غیرفعال میکند. اگر عملکرد دستگاه در طول فشار حافظه تحت تأثیر قرار گیرد، در حالی که استفاده از تعویض زیاد است و سطح تعویض آزاد به ro.lmk.swap_free_low_percentage کاهش نمییابد، مقدار را کاهش دهید تا استفاده از تعویض محدود شود. | 100 | 100 |
دکمههای تنظیم قدیمی زیر نیز با استراتژی جدید killing کار میکنند.
| ملک | استفاده کنید | پیشفرض | |
|---|---|---|---|
| عملکرد بالا | رم پایین | ||
ro.lmk.swap_free_low_percentage | سطح فضای swap آزاد به عنوان درصدی از کل فضای swap. `lmkd` از این مقدار به عنوان آستانهای برای زمانی که سیستم را به عنوان فضای swap خالی در نظر بگیریم، استفاده میکند. اگر `lmkd` در حالی که فضای swap زیادی وجود دارد، عملیات را متوقف کند، درصد را کاهش دهید. اگر عملیات نابود کردن `lmkd` خیلی دیر اتفاق بیفتد و اجازه دهد عملیات نابود کردن OOM اتفاق بیفتد، درصد را افزایش دهید. | 20 | 10 |
ro.lmk.debug | این کار گزارشهای اشکالزدایی `lmkd` را فعال میکند. اشکالزدایی را هنگام تنظیم فعال کنید. | false | |