Proces demona niskiego poziomu pamięci systemu Android ( lmkd
) monitoruje stan pamięci działającego systemu Android i reaguje na duże obciążenie pamięci, zabijając najmniej istotne procesy, aby utrzymać wydajność systemu na akceptowalnym poziomie.
O presji pamięci
W systemie Android uruchamiającym wiele procesów równolegle mogą wystąpić sytuacje, w których pamięć systemowa jest wyczerpana, a procesy wymagające większej ilości pamięci doświadczają zauważalnych opóźnień. Ciśnienie pamięci , czyli stan, w którym w systemie zaczyna brakować pamięci, wymaga od Androida zwolnienia pamięci (aby złagodzić obciążenie) poprzez ograniczanie lub kończenie nieistotnych procesów, żądanie od procesów zwolnienia niekrytycznych zasobów z pamięci podręcznej i tak dalej.
Historycznie rzecz biorąc, system Android monitorował ciśnienie pamięci systemowej za pomocą wbudowanego w jądro sterownika Low Memory Killer (LMK) – sztywnego mechanizmu zależnego od zakodowanych na stałe wartości. Począwszy od jądra 4.12, sterownik LMK został usunięty z jądra nadrzędnego, a lmkd
w przestrzeni użytkownika wykonuje zadania monitorowania pamięci i zabijania procesów.
Informacje o przestoju ciśnieniowym
Android 10 i nowsze wersje obsługują nowy tryb lmkd
, który wykorzystuje monitory informacji o przestoju jądra (PSI) do wykrywania ciśnienia pamięci. Zestaw poprawek PSI w jądrze nadrzędnym (przeniesiony do jąder 4.9 i 4.14) mierzy ilość czasu, o jaki zadania są opóźnione w wyniku niedoborów pamięci. Ponieważ te opóźnienia bezpośrednio wpływają na wygodę użytkownika, stanowią wygodną metrykę do określania dotkliwości wykorzystania pamięci. Jądro nadrzędne zawiera również monitory PSI, które umożliwiają procesom uprzywilejowanej przestrzeni użytkownika (takim jak lmkd
) określanie progów dla tych opóźnień i subskrybowanie zdarzeń z jądra w przypadku przekroczenia progu.
Monitory PSI w porównaniu z sygnałami ciśnienia vm
Ponieważ sygnały vmpressure
(generowane przez jądro do wykrywania obciążenia pamięci i używane przez lmkd
) często zawierają wiele fałszywych alarmów, lmkd
musi przeprowadzić filtrowanie, aby określić, czy pamięć jest pod rzeczywistym obciążeniem. Powoduje to niepotrzebne wybudzanie lmkd
i użycie dodatkowych zasobów obliczeniowych. Korzystanie z monitorów PSI zapewnia dokładniejsze wykrywanie obciążenia pamięci i minimalizuje obciążenie związane z filtrowaniem.
Użyj monitorów PSI
Aby używać monitorów PSI zamiast zdarzeń vmpressure
, skonfiguruj właściwość ro.lmk.use_psi
. Wartość domyślna to true
, co sprawia , że PSI monitoruje domyślny mechanizm wykrywania obciążenia pamięci dla lmkd
. Ponieważ monitory PSI wymagają obsługi jądra, jądro musi zawierać poprawki backportu PSI i być skompilowane z włączoną obsługą PSI ( CONFIG_PSI=y
).
Wady wbudowanego sterownika LMK
Android wycofuje sterownik LMK z powodu wielu problemów, w tym:
- Urządzenia z małą ilością pamięci RAM musiały być agresywnie dostrajane, a nawet wtedy słabo radziły sobie z obciążeniami z aktywną pamięcią podręczną opartą na dużych plikach. Słabe wyniki spowodowały bicie i brak zabójstw.
- Sterownik jądra LMK opierał się na limitach wolnej pamięci, bez skalowania w oparciu o wykorzystanie pamięci.
- Ze względu na sztywność konstrukcji partnerzy często dostosowywali sterownik tak, aby działał na ich urządzeniach.
- Sterownik LMK podłączył się do API modułu zmniejszania płyt, które nie zostało zaprojektowane do ciężkich operacji, takich jak wyszukiwanie celów i zabijanie ich, co spowalniało proces
vmscan
.
Przestrzeń użytkownika lmkd
lmkd
przestrzeni użytkownika implementuje tę samą funkcjonalność, co sterownik wbudowany w jądro, ale wykorzystuje istniejące mechanizmy jądra do wykrywania i szacowania wykorzystania pamięci. Takie mechanizmy obejmują wykorzystanie generowanych przez jądro zdarzeń vmpressure
lub monitorów informacji o przeciągnięciu ciśnienia (PSI) w celu uzyskania powiadomień o poziomach wykorzystania pamięci oraz wykorzystanie funkcji cgroup pamięci w celu ograniczenia zasobów pamięci przydzielonych każdemu procesowi na podstawie ważności procesu.
Użyj przestrzeni użytkownika lmkd w Androidzie 10
W systemie Android 9 i nowszych wersjach lmkd
przestrzeni użytkownika aktywuje się, jeśli nie zostanie wykryty wbudowany w jądro sterownik LMK. Ponieważ lmkd
przestrzeni użytkownika wymaga obsługi przez jądro cgrup pamięci, jądro musi zostać skompilowane z następującymi ustawieniami konfiguracyjnymi:
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
Strategie zabijania
lmkd
przestrzeni użytkownika obsługuje strategie zabijania oparte na zdarzeniach vmpressure
lub monitorach PSI, ich ważności i innych wskazówkach, takich jak wykorzystanie wymiany. Strategie zabijania różnią się w przypadku urządzeń o małej ilości pamięci i urządzeniach o wysokiej wydajności:
- Na urządzeniach o małej ilości pamięci system powinien tolerować większe wykorzystanie pamięci w normalnym trybie działania.
- Na urządzeniach o wysokiej wydajności obciążenie pamięci należy postrzegać jako sytuację nienormalną i naprawiać je, zanim wpłynie to na ogólną wydajność.
Strategię zabijania można skonfigurować za pomocą właściwości ro.config.low_ram
. Aby uzyskać szczegółowe informacje, zobacz Konfiguracja małej ilości pamięci RAM .
Userspace lmkd
obsługuje także starszy tryb, w którym podejmuje decyzje o zakończeniu działania, korzystając z tych samych strategii, co wbudowany w jądro sterownik LMK (to znaczy progi wolnej pamięci i pamięci podręcznej plików). Aby włączyć tryb starszej wersji, ustaw właściwość ro.lmk.use_minfree_levels
na true
.
Skonfiguruj lmkd
Skonfiguruj lmkd
dla konkretnego urządzenia, korzystając z poniższych właściwości.
Nieruchomość | Używać | Domyślny |
---|---|---|
ro.config.low_ram | Określ, czy urządzenie ma małą ilość pamięci RAM, czy urządzenie o wysokiej wydajności. | false |
ro.lmk.use_psi | Używaj monitorów PSI (zamiast zdarzeń vmpressure ). | true |
ro.lmk.use_minfree_levels | Użyj progów wolnej pamięci i pamięci podręcznej plików do podejmowania decyzji o zakończeniu procesu (to znaczy dopasuj funkcjonalność wbudowanego sterownika LMK). | false |
ro.lmk.low | Minimalny wynik oom_adj dla procesów, które mogą zostać zabite przy niskim poziomie vmpressure . | 1001 (wyłączony) |
ro.lmk.medium | Minimalny wynik oom_adj dla procesów, które można zabić przy średnim poziomie vmpressure . | 800 (usługi buforowane lub nieistotne) |
ro.lmk.critical | Minimalny wynik oom_adj dla procesów, które mogą zostać zakończone przy krytycznym poziomie vmpressure . | 0 (dowolny proces) |
ro.lmk.critical_upgrade | Włącz aktualizację do poziomu krytycznego. | false |
ro.lmk.upgrade_pressure | Maksymalne mem_pressure przy którym poziom jest aktualizowany, ponieważ system za dużo podmienia. | 100 (wyłączony) |
ro.lmk.downgrade_pressure | Minimalne mem_pressure , przy którym zdarzenie vmpressure jest ignorowane, ponieważ jest jeszcze dostępna wystarczająca ilość wolnej pamięci. | 100 (wyłączony) |
ro.lmk.kill_heaviest_task | Zabij najcięższe kwalifikujące się zadanie (najlepsza decyzja) w porównaniu z dowolnym kwalifikującym się zadaniem (szybka decyzja). | true |
ro.lmk.kill_timeout_ms | Czas trwania w milisekundach po zabiciu, gdy nie zostanie wykonane żadne dodatkowe zabójstwo. | 0 (wyłączony) |
ro.lmk.debug | Włącz dzienniki debugowania lmkd . | false |
Przykładowa konfiguracja urządzenia:
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
Przestrzeń użytkownika lmkd w Androidzie 11
Android 11 ulepsza lmkd
wprowadzając nową strategię zabijania. Strategia zabijania wykorzystuje mechanizm PSI do wykrywania obciążenia pamięci wprowadzony w Androidzie 10. lmkd
w Androidzie 11 uwzględnia poziomy wykorzystania zasobów pamięci i szarpanie, aby zapobiec głodowi pamięci i spadkowi wydajności. Ta strategia zabijania zastępuje poprzednie strategie i można jej używać zarówno na urządzeniach o wysokiej wydajności, jak i urządzeniach z małą ilością pamięci RAM (Android Go).
Wymagania jądra
W przypadku urządzeń z systemem Android 11 lmkd
wymaga następujących funkcji jądra:
- Dołącz poprawki PSI i włącz PSI (backporty dostępne we wspólnych jądrach Androida 4.9, 4.14 i 4.19).
- Dołącz poprawki obsługi PIDFD (backporty dostępne we wspólnych jądrach Androida 4.9, 4.14 i 4.19).
- W przypadku urządzeń z małą ilością pamięci RAM uwzględnij grupy pamięci.
Jądro musi być skompilowane z następującymi ustawieniami konfiguracyjnymi:
CONFIG_PSI=y
Skonfiguruj lmkd w Androidzie 11
Strategia zabijania pamięci w systemie Android 11 obsługuje pokrętła strojenia i ustawienia domyślne wymienione poniżej. Funkcje te działają zarówno na urządzeniach o wysokiej wydajności, jak i na urządzeniach z małą ilością pamięci RAM.
Nieruchomość | Używać | Domyślny | |
---|---|---|---|
Wysoka wydajność | Niska pamięć RAM | ||
ro.lmk.psi_partial_stall_ms | Próg częściowego przeciągnięcia PSI w milisekundach wyzwalający powiadomienie o braku pamięci. Jeśli urządzenie zbyt późno otrzymuje powiadomienia o zużyciu pamięci, zmniejsz tę wartość, aby uruchomić wcześniejsze powiadomienia. Jeśli niepotrzebnie uruchamiają się powiadomienia o zużyciu pamięci, zwiększ tę wartość, aby urządzenie było mniej wrażliwe na szumy. | 70 | 200 |
ro.lmk.psi_complete_stall_ms | Całkowity próg przeciągnięcia PSI w milisekundach wyzwalający powiadomienia o pamięci krytycznej. Jeśli urządzenie zbyt późno otrzyma powiadomienia o krytycznym zużyciu pamięci, zmniejsz tę wartość, aby uruchomić wcześniejsze powiadomienia. Jeśli niepotrzebnie uruchomią się powiadomienia o krytycznym zużyciu pamięci, zwiększ tę wartość, aby urządzenie było mniej wrażliwe na szum. | 700 | |
ro.lmk.thrashing_limit | Maksymalna liczba ponownych ustawień zestawu roboczego jako procent całkowitego rozmiaru pamięci podręcznej pliku. Błędy zestawu roboczego powyżej tej wartości oznaczają, że uznaje się, że system niszczy pamięć podręczną stronicowania. Jeśli wykorzystanie pamięci ma wpływ na wydajność urządzenia, zmniejsz wartość, aby ograniczyć zakłócenia. Jeśli wydajność urządzenia niepotrzebnie spada z powodu szarpania, zwiększ wartość, aby umożliwić większe szarpanie. | 100 | 30 |
ro.lmk.thrashing_limit_decay | Spadek progu drgań wyrażony jako procent pierwotnego progu używanego do obniżenia progu, gdy system nie może się zregenerować, nawet po zabiciu. Jeśli ciągłe bicie powoduje niepotrzebne zabójstwa, zmniejsz wartość. Jeśli reakcja na ciągłe bicie po zabiciu jest zbyt wolna, zwiększ wartość. | 10 | 50 |
ro.lmk.swap_util_max | Maksymalna ilość wymienianej pamięci jako procent całkowitej pamięci wymienialnej. Kiedy ilość wymienianej pamięci przekroczy ten limit, oznacza to, że system wymienił większość swojej pamięci wymiennej i nadal znajduje się pod presją. Może się to zdarzyć, gdy alokacje niewymienne generują obciążenie pamięci, którego nie można zmniejszyć poprzez zamianę, ponieważ większość pamięci wymiennej została już wymieniona. Wartość domyślna to 100, co skutecznie wyłącza tę kontrolę. Jeśli zużycie pamięci ma wpływ na wydajność urządzenia, gdy wykorzystanie wymiany jest wysokie, a poziom darmowej wymiany nie spada do ro.lmk.swap_free_low_percentage , zmniejsz wartość, aby ograniczyć wykorzystanie wymiany. | 100 | 100 |
Poniższe stare pokrętła strojenia działają również z nową strategią zabijania.
Nieruchomość | Używać | Domyślny | |
---|---|---|---|
Wysoka wydajność | Niska pamięć RAM | ||
ro.lmk.swap_free_low_percentage | Poziom darmowej wymiany jako procent całkowitej przestrzeni wymiany. `lmkd` używa tej wartości jako progu, kiedy należy uznać system za pozbawiony przestrzeni wymiany. Jeśli `lmkd` zabije, gdy w zamian jest za dużo miejsca, zmniejsz wartość procentową. Jeśli zabójstwa `lmkd` zdarzają się zbyt późno, pozwalając na zabójstwa OOM, zwiększ wartość procentową. | 20 | 10 |
ro.lmk.debug | Włącza to dzienniki debugowania `lmkd`. Włącz debugowanie podczas dostrajania. | false |