دیمون قاتل حافظه کم

فرآیند حذف حافظه کم اندروید ( 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