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

فرآیند اندروید کم حافظه کشنده دیمون ( lmkd ) وضعیت حافظه یک سیستم اندرویدی در حال اجرا را کنترل می کند و به فشار بالای حافظه با از بین بردن کمترین فرآیندهای ضروری برای حفظ عملکرد سیستم در سطوح قابل قبول واکنش نشان می دهد.

درباره فشار حافظه

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

از لحاظ تاریخی، اندروید فشار حافظه سیستم را با استفاده از یک درایور کشنده حافظه کم (LMK) درون هسته کنترل می‌کرد، مکانیزم سختی که به مقادیر رمزگذاری شده بستگی دارد. از هسته 4.12، درایور LMK از هسته بالادست حذف می شود و فضای کاربر lmkd نظارت بر حافظه و وظایف کشتن فرآیند را انجام می دهد.

اطلاعات ایستگاه فشار

اندروید 10 و نسخه‌های جدیدتر از حالت جدید lmkd پشتیبانی می‌کند که از مانیتورهای اطلاعات توقف فشار هسته (PSI) برای تشخیص فشار حافظه استفاده می‌کند. پچ‌ست PSI در هسته بالادست (که به هسته‌های 4.9 و 4.14 پشتیبان‌گیری می‌شود) مدت زمانی را که کارها در نتیجه کمبود حافظه به تأخیر می‌افتند، اندازه‌گیری می‌کند. از آنجایی که این تاخیرها مستقیماً بر تجربه کاربر تأثیر می‌گذارند، معیاری مناسب برای تعیین شدت فشار حافظه هستند. هسته بالادستی همچنین شامل مانیتورهای PSI است که به فرآیندهای فضای کاربران ممتاز (مانند lmkd ) اجازه می‌دهد تا آستانه‌هایی را برای این تأخیرها مشخص کنند و در صورت شکسته شدن آستانه، در رویدادهایی از هسته مشترک شوند.

مانیتورهای PSI در مقابل سیگنال های vmpressure

از آنجایی که سیگنال‌های vmpressure (که توسط هسته برای تشخیص فشار حافظه تولید می‌شوند و توسط lmkd استفاده می‌شوند) اغلب شامل موارد مثبت کاذب متعددی می‌شوند، lmkd باید فیلتر را انجام دهد تا تعیین کند که آیا حافظه تحت فشار واقعی است یا خیر. این منجر به بیدار شدن غیر ضروری lmkd و استفاده از منابع محاسباتی اضافی می شود. استفاده از نمایشگرهای PSI منجر به تشخیص دقیق‌تر فشار حافظه می‌شود و سربار فیلتر را به حداقل می‌رساند.

استفاده از مانیتورهای PSI

برای استفاده از نمایشگرهای PSI به جای رویدادهای vmpressure ، ویژگی ro.lmk.use_psi را پیکربندی کنید. پیش‌فرض true است و باعث می‌شود PSI مکانیسم پیش‌فرض تشخیص فشار حافظه برای lmkd را مانیتور کند. از آنجایی که مانیتورهای PSI به پشتیبانی هسته نیاز دارند، هسته باید شامل وصله‌های پشتیبان PSI باشد و با پشتیبانی PSI فعال شده ( CONFIG_PSI=y ) کامپایل شود.

معایب درایور LMK درون هسته

Android درایور LMK را به دلیل تعدادی از مشکلات منسوخ می کند، از جمله:

  • دستگاه‌های با رم پایین باید به شدت تنظیم می‌شدند، و حتی در آن زمان در بارهای کاری با کش صفحه فعال با پشتوانه فایل‌های بزرگ عملکرد ضعیفی داشتند. عملکرد ضعیف منجر به ضرب و شتم و بدون کشتن شد.
  • درایور هسته LMK به محدودیت‌های حافظه آزاد متکی بود، بدون اینکه مقیاسی بر اساس فشار حافظه ایجاد شود.
  • به دلیل استحکام طراحی، شرکا اغلب درایور را سفارشی می کردند تا روی دستگاه هایشان کار کند.
  • درایور LMK به API کوچک‌کننده اسلب متصل شد، که برای عملیات‌های سنگین مانند جستجوی اهداف و کشتن آنها طراحی نشده بود، که روند vmscan را کند کرد.

فضای کاربری lmkd

Userspace lmkd همان عملکرد درایور درون هسته را پیاده سازی می کند اما از مکانیسم های هسته موجود برای تشخیص و تخمین فشار حافظه استفاده می کند. چنین مکانیزم‌هایی شامل استفاده از رویدادهای vmpressure تولید شده توسط هسته یا نمایشگرهای اطلاعات توقف فشار (PSI) برای دریافت اعلان‌های مربوط به سطوح فشار حافظه و استفاده از ویژگی‌های cgroup حافظه برای محدود کردن منابع حافظه تخصیص یافته به هر فرآیند بر اساس اهمیت فرآیند است.

استفاده از userspace lmkd در اندروید 10

در اندروید 9 و جدیدتر، اگر درایور LMK درون هسته شناسایی نشود، userspace lmkd فعال می شود. از آنجایی که userspace lmkd به پشتیبانی هسته برای cgroup های حافظه نیاز دارد، هسته باید با تنظیمات پیکربندی زیر کامپایل شود:

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

استراتژی های کشتن

Userspace lmkd از استراتژی‌های کشتن مبتنی بر رویدادهای vmpressure یا نمایشگرهای PSI، شدت آنها و نکات دیگری مانند استفاده از مبادله پشتیبانی می‌کند. استراتژی‌های کشتن بین دستگاه‌های با حافظه کم و عملکرد بالا متفاوت است:

  • در دستگاه های با حافظه کم، سیستم باید فشار حافظه بالاتری را به عنوان یک حالت عادی کار تحمل کند.
  • در دستگاه‌های با کارایی بالا، فشار حافظه باید به‌عنوان یک وضعیت غیرعادی در نظر گرفته شود و قبل از اینکه بر عملکرد کلی تأثیر بگذارد، رفع شود.

می توانید استراتژی kill را با استفاده از ویژگی ro.config.low_ram پیکربندی کنید. برای جزئیات، به پیکربندی رم کم مراجعه کنید.

Userspace lmkd همچنین از حالت قدیمی پشتیبانی می‌کند که در آن با استفاده از استراتژی‌های مشابه درایور 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 بحرانی. 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 سنگین ترین کار واجد شرایط (بهترین تصمیم) را در مقابل هر کار واجد شرایط (تصمیم سریع) بکشید. true
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 در اندروید 11

اندروید 11 با معرفی یک استراتژی جدید کشتار، lmkd را بهبود می بخشد. استراتژی کشتن از یک مکانیسم PSI برای تشخیص فشار حافظه استفاده می‌کند lmkd در اندروید 10 معرفی شده است. این استراتژی کشتار جایگزین استراتژی‌های قبلی می‌شود و می‌تواند در دستگاه‌های با عملکرد بالا و رم پایین (Android Go) استفاده شود.

الزامات هسته

برای دستگاه های اندروید 11، lmkd به ویژگی های هسته زیر نیاز دارد:

  • وصله‌های PSI را اضافه کنید و PSI را فعال کنید (پس‌پورت‌های موجود در هسته‌های رایج اندروید ۴.۹، ۴.۱۴ و ۴.۱۹).
  • شامل وصله‌های پشتیبانی PIDFD (پشت‌پورت‌های موجود در هسته‌های رایج اندروید 4.9، 4.14 و 4.19).
  • برای دستگاه‌هایی که RAM پایینی دارند، cgroup‌های حافظه را در نظر بگیرید.

هسته باید با تنظیمات پیکربندی زیر کامپایل شود:

CONFIG_PSI=y

پیکربندی lmkd در اندروید 11

استراتژی کشتن حافظه در اندروید 11 از دکمه های تنظیم و پیش فرض های ذکر شده در زیر پشتیبانی می کند. این ویژگی‌ها هم در دستگاه‌های با کارایی بالا و هم در دستگاه‌های با رم پایین کار می‌کنند.

ویژگی استفاده کنید پیش فرض
عملکرد بالا رم کم
ro.lmk.psi_partial_stall_ms آستانه توقف جزئی PSI، در میلی ثانیه، برای راه اندازی اعلان حافظه کم. اگر دستگاه اعلان‌های فشار حافظه را خیلی دیر دریافت کرد، این مقدار را کاهش دهید تا اعلان‌های زودتر فعال شوند. اگر اعلان‌های فشار حافظه غیرضروری فعال می‌شوند، این مقدار را افزایش دهید تا دستگاه نسبت به نویز حساسیت کمتری داشته باشد. 70 200
ro.lmk.psi_complete_stall_ms آستانه کامل PSI، در میلی ثانیه، برای راه اندازی اعلان های حافظه حیاتی. اگر دستگاه اعلان‌های فشار بحرانی حافظه را خیلی دیر دریافت کرد، این مقدار را کاهش دهید تا اعلان‌های زودتر فعال شوند. اگر اعلان‌های فشار بحرانی حافظه غیرضروری فعال می‌شوند، این مقدار را افزایش دهید تا دستگاه نسبت به نویز حساسیت کمتری داشته باشد. 700
ro.lmk.thrashing_limit حداکثر مقدار خطاهای مجموعه کاری به عنوان درصدی از کل اندازه کش صفحه پشتیبان شده فایل. خطاهای مجموعه کاری بالاتر از این مقدار به این معنی است که سیستم در نظر گرفته می شود که صفحه کش خود را thrash می کند. اگر عملکرد دستگاه در حین فشار حافظه تحت تأثیر قرار می‌گیرد، مقدار را کاهش دهید تا ضربه زدن را محدود کنید. اگر عملکرد دستگاه به دلایل کوبیدن غیرضروری از بین رفت، مقدار را افزایش دهید تا امکان کوبیدن بیشتر فراهم شود. 100 30
ro.lmk.thrashing_limit_decay فروپاشی آستانه کوبنده به صورت درصدی از آستانه اولیه استفاده شده برای پایین آوردن آستانه زمانی که سیستم بازیابی نمی شود، حتی پس از کشتن بیان می شود. اگر کوبیدن مداوم باعث کشتن غیر ضروری می شود، مقدار را کاهش دهید. اگر پاسخ به کوبیدن مداوم پس از کشتن خیلی کند است، مقدار را افزایش دهید. 10 50
ro.lmk.swap_util_max حداکثر مقدار حافظه تعویض شده به عنوان درصدی از کل حافظه قابل تعویض. هنگامی که حافظه swapped بیش از این حد رشد می کند، به این معنی است که سیستم بیشتر حافظه قابل تعویض خود را تعویض کرده و همچنان تحت فشار است. این ممکن است زمانی اتفاق بیفتد که تخصیص‌های غیرقابل تعویض فشار حافظه ایجاد می‌کنند که با تعویض نمی‌توان آن را کاهش داد زیرا بیشتر حافظه قابل تعویض قبلاً تعویض شده است. مقدار پیش فرض 100 است که عملاً این بررسی را غیرفعال می کند. اگر عملکرد دستگاه در حین فشار حافظه تحت تأثیر قرار می گیرد، در حالی که استفاده از مبادله زیاد است و سطح مبادله رایگان به ro.lmk.swap_free_low_percentage کاهش نمی یابد، مقدار را کاهش دهید تا استفاده از مبادله محدود شود. 100 100

دستگیره های تنظیم قدیمی زیر نیز با استراتژی جدید کشتار کار می کنند.

ویژگی استفاده کنید پیش فرض
عملکرد بالا رم کم
ro.lmk.swap_free_low_percentage سطح مبادله رایگان به عنوان درصدی از کل فضای مبادله. «lmkd» از این مقدار به‌عنوان آستانه‌ای برای زمان در نظر گرفتن سیستم به عنوان فضای مبادله گرسنگی استفاده می‌کند. اگر «lmkd» می کشد در حالی که فضای زیادی در مبادله وجود دارد، درصد را کاهش دهید. اگر کشتن‌های «lmkd» خیلی دیر اتفاق می‌افتند، با اجازه دادن به کشتن‌های OOM، درصد را افزایش دهید. 20 10
ro.lmk.debug این گزارش‌های اشکال‌زدایی «lmkd» را فعال می‌کند. هنگام تنظیم، اشکال زدایی را فعال کنید. false