kswapd ve lmkd etkileşimi

Bu sayfada, Android'de kswapd ile lmkd arasındaki etkileşim ele alınmakta ve bellek baskısını yönetmek için birlikte nasıl çalıştıkları gösterilmektedir.

Arka plan

Android, sistemde bellek azaldığında belleği geri kazanmak için iki temel mekanizma kullanır:

  1. kswapd: Temiz dosya destekli sayfaları çıkararak veya anonim sayfaları ZRAM ile değiştirerek sayfaları geri alan standart bir Linux çekirdeği arka plan programı.
  2. lmkd: Android'in kullanıcı alanındaki Low Memory Killer arka plan programı. kswapd, bellek taleplerini karşılayamadığında ve sistem baskısı arttığında (PSI tarafından belirtildiği gibi) lmkd, daha büyük bellek parçalarını boşaltmak için işlemleri sonlandırır.

kswapd ve lmkd, birbirini tamamlayan iki bellek geri kazanma sistemidir. Aynı amaca (boş bellek oluşturma) farklı yöntemlerle ulaşmaya çalışırlar. Karşılaştırma ve ayırt etme:

  • Kurtarılabilir ve yıkıcı: kswapd, depolama alanından geri okunabilen bellek sayfalarını bırakır veya bellek sayfalarını, isteğe bağlı olarak geri okunabilen diğer bellek bölümleri ya da depolama alanıyla değiştirir. lmkd, işlemleri sonlandırarak geçici olmayan durumu yok eder.
  • Bant genişliğini geri kazanma: kswapd, belirli bir miktarda boş belleği geri kazanmak için lmkd'ten daha fazla CPU harcar ve söz konusu belleği geri kazanması daha uzun sürer. lmkd, kısa süreli ve nispeten az çaba gerektiren işlemlerle büyük miktarda bellek geri kazanabilir. Mobil cihazlarda CPU kullanımının yalnızca gecikmeye değil, pil gücüne de etki ettiğini unutmayın.

OOM puanı grupları

Android, kullanıcı için önemlerine göre işlemlere bir bellek yetersiz (OOM) puan ayarlaması (oom_score_adj) atar. Puanı daha yüksek olan işlemler önce sonlandırılır.

Yaygın gruplar şunlardır:

  • Önbelleğe alınan (Puan >= 900): Şu anda gerekli olmayan, daha hızlı yeniden başlatma için saklanan işlemler.
  • Hizmet (Puan 500): Başlatılan hizmetleri barındıran işlemler.
  • Ön Plan Hizmeti (Puan 200): Ön plan hizmetlerini barındıran işlemler.
  • Ön plan (Puan 0): Kullanıcının o anda etkileşimde bulunduğu uygulama.

Ayrıntılı inceleme: PSI ve LMKD tetikleme

PSI nedir?

Pressure Stall Information (PSI), kaynak eksikliklerini ölçmek için standart bir yöntem sunan bir Linux çekirdeği özelliğidir. CPU, bellek ve G/Ç eksikliği nedeniyle görevlerin ne kadar geciktiğini takip eder.

Bellek PSI: "some" ve "full" karşılaştırması

Bellek PSI, özellikle bellek yetersizliğinden kaynaklanan gecikmeleri (ör. sayfa geri alma veya yeniden hata için bekleme) izler. İki metrik sağlar:

  • some: En az bir görevin bellekte duraklatıldığı sürenin yüzdesi. Bu durum, bellek yetersizliğinin performansı etkilediğini ancak bazı işlemlerin devam ettiğini gösterir.
  • full: Boşta olmayan tüm görevlerin aynı anda duraklatıldığı sürenin yüzdesi. Bu, sistemin tamamen engellendiği ve bellek beklediği kritik bir durumu gösterir.

PSI, LMKD'yi nasıl tetikler?

Kullanıcı alanındaki lmkd arka plan programı, PSI eşikleri aşıldığında (/proc/pressure/memory izlenerek) bildirim almak için çekirdeğe kaydolur. Sistemde yüksek bellek baskısı olduğunda (ör. full duraklaması yapılandırılmış bir süreyi aştığında) çekirdek, lmkd programını uyandırır. lmkd, sistemin durumunu değerlendirir ve OOM puanlarına ve boyutlarına göre işlemlerin sonlandırılıp sonlandırılmayacağına ve hangilerinin sonlandırılacağına karar verir.

LMKD ayarlama

LMKD davranışı, sistem özellikleri kullanılarak ayarlanabilir.

Cihazda ayarlama değerlerini bulma

Bağlı bir cihazdaki mevcut LMKD ayar değerlerini görmek için şu komutu çalıştırabilirsiniz:

adb shell getprop | grep lmk

Yaygın LMKD özellikleri

LMKD'yi ayarlamak için kullanılan temel özelliklerden bazıları şunlardır (tam liste için Android belgelerine bakın):

  • ro.lmk.use_psi: Bellek baskısı algılama için PSI monitörlerini kullanmak üzere true olarak ayarlayın (Android 10 ve sonraki sürümlerde varsayılan).
  • ro.lmk.psi_partial_stall_ms: Sonlandırmayı tetiklemek için milisaniye cinsinden some (kısmi) duraklama süresi eşiği (normal cihazlarda varsayılan olarak 70 ms, düşük RAM'li cihazlarda 200 ms).
  • ro.lmk.psi_complete_stall_ms: Sonlandırmayı tetiklemek için milisaniye cinsinden full duraklama süresi eşiği (varsayılan 700 ms).
  • ro.lmk.kill_heaviest_task: true ise LMKD, aynı OOM grubundaki adaylar arasında en fazla bellek kullanan işlemi sonlandırır.

Test cihazındaki (Google Pixel 8 Pro) ilgili ayarlama değerleri

(Not: Android 15 yüklü üst düzey cihazlar için tipik varsayılan değerler)

  • ro.lmk.use_psi: true
  • ro.lmk.psi_partial_stall_ms: 70 (tipik)
  • ro.lmk.psi_complete_stall_ms: 700 (tipik)
  • ro.lmk.kill_heaviest_task: true

ZRAM ve takas doğrulama

ZRAM kapasitesi, takas alanının ne kadar hızlı dolduğunu ve LMKD sonlandırmalarını tetiklediğini büyük ölçüde etkiler. Aşağıdaki komutları kullanarak cihazdaki ZRAM ve takas durumunu kontrol edebilirsiniz:

# Check ZRAM sizing and usage
adb shell free -m

# Check swap partition details
adb shell cat /proc/swaps

Pratik alıştırma: kswapd ve lmkd'yi tetikleme

Bu alıştırmada, farklı OOM gruplarında işlemler oluşturmak için KswapdLmkdLab örnek uygulamasını kullanacak, ardından kswapd ve lmkd işlemlerini tetiklemek için ana işlemde bellek kullanacaksınız.

Uygulama, otomatik olarak alt işlemler oluşturacak ve bunları LMKD için cazip hedefler haline getirmek üzere bellek ayıracak şekilde yapılandırılmıştır.

1. Alt süreçler oluşturma

Uygulama, başlatıldığında aşağıdaki alt işlemleri otomatik olarak oluşturur:

  • Önbelleğe Alınmış İşlem (oom_score_adj >= 900)
  • Hizmet İşlemi (oom_score_adj 500)
  • Ön Plan Hizmeti İşlemi (oom_score_adj 200)

ADB'yi kullanarak işlemleri ve OOM puanlarını doğrulayın:

adb shell dumpsys activity processes | grep com.android.kswapdlmkdlab

Örnek Çıkış Snippet'i:

    Proc #  0: fg       T/A/TOP  LCMNFUATI  t: 0 18959:com.android.kswapdlmkdlab/u0a358 (top-activity)
    Proc #  1: prcp     b/ /FGS  -------TI  t: 0 19050:com.android.kswapdlmkdlab:foreground/u0a358 (fg-service)
    Proc #  2: svc      b/ /SVC  -------TI  t: 0 19077:com.android.kswapdlmkdlab:service/u0a358 (started-services)
    Proc #  3: cch      b/ /CACC -------TI  t: 0 19014:com.android.kswapdlmkdlab:cached/u0a358 (cch-client-act)

İşlem durumu kısaltmaları şunlara karşılık gelir:

  • fg: Ön plan (OOM puanı 0)
  • prcp: Algılanabilir (Ön plan hizmeti, OOM puanı 200)
  • svc: Başlatılan Hizmet (OOM puanı 500)
  • cch: Önbelleğe Alınmış İşlem (OOM puanı 900)

2. Bellek baskısını tetikleme

Uygulama, ana işlemde otomatik olarak bellek ayırmaya başlar. Testin yüksek RAM'li cihazlarda etkili olması için uygulama, alt işlemlere bellek ayırma (ör. her biri 500 MB) komutu vererek bu işlemleri LMKD için daha iyi hedefler haline getirir.

Alt işlem sonlandırmayı izleme

Uygulama, IBinder.linkToDeath mekanizmasını kullanarak bu alt işlemlerin sonlandırılmasını izler:

  1. Ana işlem, bindService kullanarak hedef işlemdeki bir hizmete bağlanır.
  2. Bağlantı kurulduğunda hizmeti temsil eden IBinder nesnesini alır.
  3. Bağlayıcıda linkToDeath çağrısı yaparak bir IBinder.DeathRecipient uygulamasını kaydeder.
  4. Hedef işlem sonlandığında (örneğin, LMKD tarafından sonlandırıldığında) sistem, binderDied() yöntemini çağırarak uygulamanın sonlandırma etkinliğini eşzamansız olarak kaydetmesine olanak tanır.

Uygulama, bu bağlamanın hedef işlemlerin önceliğini yükseltmesini (bu da alıştırmanın amacını bozar) önlemek için Context.BIND_WAIVE_PRIORITY işaretini kullanır.

Örnek uygulamanın kullanımı

Google Pixel 8 Pro'da (toplam RAM yaklaşık 12 GB) test çalıştırması tamamlandıktan sonra uygulamanın ekran görüntüsü aşağıda verilmiştir.

Tamamlanan bir test çalıştırmasından sonra örnek uygulamanın ekran görüntüsü.
Şekil 1. Pixel 8 Pro'da tamamlanan test çalıştırmasından sonra örnek uygulama.

Perfetto izleme analizi

Etkileşimi yakalamak için aşağıdaki Perfetto yapılandırmasını kullanarak planlama, bellek sayaçları, LMK sonlandırmaları ve Basınç Durma Bilgileri'ni (PSI) yakalayın.

Perfetto yapılandırması

Perfetto'yu zamanlama, bellek sayaçları, LMK sonlandırmaları ve Pressure Stall Information (PSI) ile çalıştırarak etkileşimi yakalayın:

adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/kswapd_lmkd.perfetto-trace <<EOF
buffers: { size_kb: 131072 }
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "lowmemorykiller/lowmemory_kill"
            ftrace_events: "vmscan/mm_vmscan_kswapd_wake"
            ftrace_events: "vmscan/mm_vmscan_kswapd_sleep"
            ftrace_events: "psi/psi_event"
        }
    }
}
duration_ms: 180000
EOF

İzi inceleme

Aşağıdaki ekran görüntüsü, :cached (en kolay sonlandırılabilir) işlemin sonlandırılmasından kısa bir süre öncesinden :foreground (en zor sonlandırılabilir) işlemin sonlandırılmasına kadar geçen süreyi gösteren bir izden alınmıştır.

kswapd ve lmkd etkinliğini gösteren Perfetto kullanıcı arayüzü ekran görüntüsü.
Şekil 2. kswapd geri kazanımını ve lmkd sonlandırmalarını gösteren Perfetto izi.

MemFree değerinin zaten oldukça düşük olduğunu ve sürekli baskı altında olduğunu görebilirsiniz. kswapd sürekli çalışıyor ve tüm kswapdlmkdlab işlemlerinden (ana işlem ve alt işlemler) ve muhtemelen bu ekran görüntüsünde gösterilmeyen diğer işlemlerden mem.rss.file sayfa bırakıp mem.rss.anon öğesini mem.swap konumuna taşıyarak baskıyı azaltıyor. Aynı zamanda kswapdlmkdlab uygulaması, bellek ayırmaya devam ederek baskıyı kswapd uygulamasının geri alabileceğinden daha hızlı artırır.

Baskı çok fazla olduğunda (psi.mem değerinin yeterli bir süre boyunca yüksek olması gibi) lmkd uyanır ve bazı işlemleri sonlandırır. lmkd'nin OOM puanlarına uyduğunu, önce kswapdlmkdlab:cached'i, ardından :service'yi ve son olarak :foreground'yi sonlandırdığını görebilirsiniz.

Olayların zaman çizelgesini inceleyin ve aşağıdakiler üzerinde düşünün:

  • kswapd ve lmkd birbirini nasıl tamamlar: kswapd, bellek baskısına ilk yanıt veren mekanizmadır ancak kswapd'nin geri alma bant genişliği, ayırma talebini karşılamadığında lmkd yardımcı olur.
  • Serbest bırakılan bellek oranı: kswapd içinde harcanan CPU süresini ve mem.rss.file bırakılarak veya mem.rss.anon, mem.swap ile değiştirilerek geri kazanılan belleği gözlemleyin. Bunu, lmkd uygulamasındaki kısa süreli etkinliklerle karşılaştırın. Bu etkinlikler, büyük miktarda özel işlem belleğinin serbest bırakılmasına neden olur.

Sorgular

İzlemenizden veri ayıklamak için bu sorguları Perfetto kullanıcı arayüzünde (Sorgu SQL) çalıştırın.

1. kswapd etkinliği

Çekirdeğin takas arka plan programının ne zaman etkin ve çalışır durumda olduğunu öğrenmek için şu komutu çalıştırın:

SELECT ts, dur, state
FROM thread_state
JOIN thread USING (utid)
WHERE thread.name LIKE 'kswapd%'
  AND state = 'Running'
LIMIT 5;

Örnek çıkış:

ts dur durum
30317633052969 159180 Çalışıyor
30317633398347 3999186 Çalışıyor
30317638448111 1847941 Çalışıyor
30317641455354 1031006 Çalışıyor
30317643272615 888387 Çalışıyor

2. LMKD sonlandırmaları

LMKD, düşük bellek nedeniyle sonlandırılan işlemleri instant tablosuna yazar. Tüm LMKD sonlandırmalarını sorgulamak için:

SELECT ts, name
FROM instant
WHERE name LIKE 'lmk,%'
ORDER BY ts ASC;

Etkinlik adı biçimi şu şekildedir: lmk,<pid>,<kill_reason>,<oom_score_adj>,<min_oom_score>,<max_thrashing>.

  • kill_reason: lmkd'nin işlemi sonlandırmaya neden karar verdiğini gösteren bir tam sayı (system/memory/lmkd/statslog.h içinde tanımlanır):
    • 0: PRESSURE_AFTER_KILL
    • 1: NOT_RESPONDING
    • 2: LOW_SWAP_AND_THRASHING (ZRAM takas alanı son derece düşük ve kesinti yaşandı)
    • 3: LOW_MEM_AND_SWAP (Sistemde hem boş bellek hem de ZRAM takas alanı az)
    • 4: LOW_MEM_AND_THRASHING
    • 5: DIRECT_RECL_AND_THRASHING
    • 6: LOW_MEM_AND_SWAP_UTIL
    • 7: LOW_FILECACHE_AFTER_THRASHING
    • 8: LOW_MEM
    • 9: DIRECT_RECL_STUCK
  • max_thrashing: Sonlandırma sırasında maksimum sayfa thrashing yüzdesi.

Örnek çıkış:

ts ad
30326148679967 lmk,2308,3,900,201,0
30330439763710 lmk,2309,3,500,201,0
30334985999837 lmk,2310,2,200,0,307

Görselleştirme

Verileri görselleştirmek için aşağıdaki gnuplot komut dosyasını kullanarak sistemin boş belleğini, kswapd etkinliğini, lmkd sonlandırmalarını ve PSI'yı tek bir zaman serisinde grafiğe dökebilirsiniz. Komut dosyasının, Android derlemesinin üst dizininden çalıştırıldığı varsayılır.

Örnek çıkış grafiği

Aşağıdaki grafik, test çalıştırmasını temsil eden örneklenmiş verilerle önceki komut dosyası kullanılarak oluşturulmuştur.

Boş bellek, kswapd etkinliği, PSI ve lmkd sonlandırmalarının grafiği.
3.şekil Boş bellek, kswapd, PSI ve lmkd sonlandırmalarını gösteren bellek baskısı grafiği.

Grafik Açıklaması:

Bu grafik, stres testi sırasında farklı bellek yönetimi bileşenleri arasındaki dinamik etkileşimi göstermektedir:

  1. Boş Bellek Düşüşü: Ana uygulama bellek ayırdıkça sistemin boş belleği (mor çizgi) sürekli olarak azalır.
  2. kswapd Etkinleştirme: Boş bellek belirli eşiklerin altına düştüğünde kswapd, ZRAM'e takas yaparak belleği geri kazanmak için uyanır (mavi sinyaller). Bu durum, aralıklı ani artışlar olarak görünür.
  3. PSI Artışları: kswapd, yüksek ayırma hızına ayak uydurmakta zorlandığı için iş parçacıkları bellek ayırma işleminde duraklamaya başlar. Bu da PSI (Basınç Duraklama Bilgisi) (yeşil çizgi) değerinin artmasına neden olur.
  4. LMKD Sonlandırmaları: PSI kritik seviyelere ulaştığında (ör.kavramsal olarak ro.lmk.psi_complete_stall_ms eşiğini aştığında) ve boş bellek son derece düşük olduğunda lmkd, düşük öncelikli işlemleri sonlandırarak (30 ve 45. saniyelerdeki turuncu darbeler) büyük bellek parçalarını boşaltır. Sonlandırma işleminden hemen sonra boş bellek artar ve PSI düşer. Bu da sonlandırma işleminin baskıyı azaltmada etkili olduğunu gösterir. ________________________________________________________________________________

← Bellek geri kazanımı: çıkarma ve takas | ↑ Yukarı | Bellek sayfalarını işletim sistemine geri döndürme →