กระบวนการ Daemon ของ Android Low Memory Killer (lmkd
) จะตรวจสอบสถานะหน่วยความจำของระบบ Android ที่ทำงานอยู่ และตอบสนองต่อการใช้หน่วยความจำสูงด้วยการหยุดกระบวนการที่มีความสำคัญน้อยที่สุดเพื่อให้ระบบทำงานในระดับที่ยอมรับได้
เกี่ยวกับแรงกดดันด้านหน่วยความจำ
ระบบ Android ที่เรียกใช้หลายกระบวนการแบบขนานอาจพบสถานการณ์ที่หน่วยความจำของระบบหมดและกระบวนการที่ต้องการหน่วยความจำเพิ่มเติมจะเกิดความล่าช้าอย่างเห็นได้ชัด แรงกดดันด้านหน่วยความจำคือสถานะที่ระบบมีหน่วยความจำไม่เพียงพอ ซึ่งทำให้ Android ต้องเพิ่มหน่วยความจำ (เพื่อลดแรงกดดัน) โดยการจำกัดหรือหยุดกระบวนการที่ไม่สำคัญ ขอให้กระบวนการต่างๆ เพิ่มทรัพยากรที่แคชไว้ซึ่งไม่สำคัญ และอื่นๆ
ในอดีต Android ตรวจสอบแรงกดดันด้านหน่วยความจำของระบบโดยใช้ไดรเวอร์
Low Memory Killer (LMK) ในเคอร์เนล ซึ่งเป็นกลไกที่เข้มงวดซึ่งขึ้นอยู่กับค่าที่ฮาร์ดโค้ด
ตั้งแต่เคอร์เนล 4.12 เป็นต้นไป ระบบได้นำไดรเวอร์ LMK ออกจากเคอร์เนลต้นทาง
และพื้นที่ผู้ใช้ lmkd
จะทำการตรวจสอบหน่วยความจำและหยุดกระบวนการ
ข้อมูลการหยุดชะงักของแรงดัน
Android 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 เนื่องจากปัญหาหลายประการ ซึ่งรวมถึงปัญหาต่อไปนี้
- อุปกรณ์ที่มี RAM ต่ำต้องได้รับการปรับแต่งอย่างเข้มงวด และแม้จะทำเช่นนั้นแล้ว ก็ยังทำงานได้ไม่ดีในเวิร์กโหลดที่มีแคชหน้าเว็บที่ใช้งานอยู่ซึ่งมีไฟล์ขนาดใหญ่เป็นข้อมูลสำรอง ประสิทธิภาพต่ำส่งผลให้เกิดการสลับหน้ามากเกินไปและไม่มีการสังหาร
- ไดรเวอร์เคอร์เนล LMK อาศัยขีดจำกัดของหน่วยความจำที่ว่าง โดยไม่มีการปรับขนาดตาม แรงกดดันด้านหน่วยความจำ
- เนื่องจากความแข็งแกร่งของการออกแบบ พาร์ทเนอร์จึงมักปรับแต่งไดรเวอร์ เพื่อให้ทำงานบนอุปกรณ์ของตนได้
- ไดรเวอร์ LMK เชื่อมต่อกับ API ของ Slab Shrinker ซึ่งไม่ได้
ออกแบบมาสําหรับการดําเนินการหนักๆ เช่น การค้นหาเป้าหมายและการ
หยุดกระบวนการ
vmscan
ซึ่งทําให้การทํางานช้าลง
lmkd ในพื้นที่ของผู้ใช้
Userspace lmkd
จะใช้ฟังก์ชันการทำงานเดียวกันกับไดรเวอร์ในเคอร์เนล
แต่จะใช้กลไกเคอร์เนลที่มีอยู่เพื่อตรวจหาและประมาณการใช้หน่วยความจำ กลไกดังกล่าวรวมถึงการใช้เหตุการณ์ vmpressure
ที่สร้างโดยเคอร์เนลหรือการตรวจสอบข้อมูลการหยุดชะงักเนื่องจากแรงดัน (PSI) เพื่อรับการแจ้งเตือนเกี่ยวกับระดับแรงดันหน่วยความจำ
และการใช้ฟีเจอร์ Cgroup หน่วยความจำเพื่อจำกัดทรัพยากรหน่วยความจำที่จัดสรรให้กับแต่ละกระบวนการ
ตามความสำคัญของกระบวนการ
ใช้ lmkd ในพื้นที่ผู้ใช้ใน Android 10
ใน Android 9 ขึ้นไป lmkd
ของพื้นที่ผู้ใช้จะเปิดใช้งานหากไม่พบไดรเวอร์ LMK ในเคอร์เนล เนื่องจาก Userspace lmkd
ต้องมีการรองรับเคอร์เนลสำหรับ Cgroup ของหน่วยความจำ คุณจึงต้องคอมไพล์เคอร์เนลด้วยการตั้งค่าการกำหนดค่าต่อไปนี้
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
กลยุทธ์การกำจัด
Userspace lmkd
รองรับกลยุทธ์การหยุดทำงานตามvmpressure
เหตุการณ์หรือ PSI
มอนิเตอร์ ความรุนแรง และคำแนะนำอื่นๆ เช่น การใช้ Swap
กลยุทธ์การหยุดทำงานจะแตกต่างกันระหว่างอุปกรณ์ที่มีหน่วยความจำต่ำกับอุปกรณ์ที่มีประสิทธิภาพสูง ดังนี้
- ในอุปกรณ์ที่มีหน่วยความจำต่ำ ระบบควรยอมรับการใช้หน่วยความจำที่สูงขึ้นใน โหมดการทำงานปกติ
- ในอุปกรณ์ที่มีประสิทธิภาพสูง คุณควรพิจารณาว่าการใช้หน่วยความจำมากเป็นสถานการณ์ที่ผิดปกติ และแก้ไขก่อนที่จะส่งผลต่อประสิทธิภาพโดยรวม
คุณกำหนดค่ากลยุทธ์การหยุดได้โดยใช้พร็อพเพอร์ตี้ ro.config.low_ram
Userspace lmkd
ยังรองรับโหมดเดิมซึ่งจะตัดสินใจปิดโดยใช้กลยุทธ์เดียวกับไดรเวอร์ LMK ในเคอร์เนล (นั่นคือ เกณฑ์หน่วยความจำว่างและแคชไฟล์) หากต้องการเปิดใช้โหมดเดิม ให้ตั้งค่าพร็อพเพอร์ตี้
ro.lmk.use_minfree_levels
เป็น true
กำหนดค่า lmkd
กำหนดค่า lmkd
สำหรับอุปกรณ์ที่เฉพาะเจาะจงโดยใช้พร็อพเพอร์ตี้ต่อไปนี้
พร็อพเพอร์ตี้ | ใช้ | ค่าเริ่มต้น |
---|---|---|
ro.config.low_ram
|
ระบุว่าอุปกรณ์เป็นอุปกรณ์ที่มี 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
|
หยุดงานที่มีสิทธิ์ซึ่งมีน้ำหนักมากที่สุด (การตัดสินใจที่ดีที่สุด) เทียบกับงานที่มีสิทธิ์ใดก็ได้ (การตัดสินใจอย่างรวดเร็ว) | 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 ในพื้นที่ผู้ใช้ใน Android 11
Android 11 ปรับปรุง lmkd
โดยการเปิดตัว
กลยุทธ์การสิ้นสุดการทำงานใหม่ กลยุทธ์การสิ้นสุดกระบวนการใช้กลไก PSI เพื่อตรวจหาแรงกดดันด้านหน่วยความจำ
ซึ่งเปิดตัวใน Android 10 lmkd
ใน Android 11 จะพิจารณาระดับการใช้ทรัพยากรหน่วยความจำ
และการสลับเพื่อป้องกันการขาดแคลนหน่วยความจำและประสิทธิภาพที่ลดลง
กลยุทธ์การปิดแอปนี้จะแทนที่กลยุทธ์ก่อนหน้า และใช้ได้ทั้งในอุปกรณ์ที่มีประสิทธิภาพสูงและอุปกรณ์ที่มี RAM น้อย (Android Go)
ข้อกำหนดของเคอร์เนล
สำหรับอุปกรณ์ Android 11 lmkd
ต้องใช้ฟีเจอร์เคอร์เนลต่อไปนี้
- รวมแพตช์ PSI และเปิดใช้ PSI (การพอร์ตย้อนหลังพร้อมใช้งานใน เคอร์เนลทั่วไปของ Android 4.9, 4.14 และ 4.19)
- รวมแพตช์การรองรับ PIDFD (การพอร์ตย้อนกลับพร้อมใช้งานในเคอร์เนลทั่วไปของ Android เวอร์ชัน 4.9, 4.14 และ 4.19)
- สำหรับอุปกรณ์ที่มี RAM ต่ำ ให้รวม Cgroup ของหน่วยความจำ
ต้องคอมไพล์เคอร์เนลด้วยการตั้งค่าต่อไปนี้
CONFIG_PSI=y
กำหนดค่า lmkd ใน Android 11
กลยุทธ์การจัดการหน่วยความจำใน Android 11 รองรับ การปรับแต่งและค่าเริ่มต้นที่ระบุไว้ด้านล่าง ฟีเจอร์เหล่านี้ใช้ได้ทั้งใน อุปกรณ์ที่มีประสิทธิภาพสูงและอุปกรณ์ที่มี RAM ต่ำ
พร็อพเพอร์ตี้ | ใช้ | ค่าเริ่มต้น | |
---|---|---|---|
ประสิทธิภาพสูง | RAM น้อย | ||
ro.lmk.psi_partial_stall_ms |
เกณฑ์การหยุดชะงักของ PSI บางส่วนเป็นมิลลิวินาทีสำหรับการเรียกใช้การแจ้งเตือนหน่วยความจำต่ำ หากอุปกรณ์ได้รับการแจ้งเตือนหน่วยความจำเหลือน้อย ช้าเกินไป ให้ลดค่านี้เพื่อทริกเกอร์การแจ้งเตือนก่อนหน้านี้ หากการแจ้งเตือนแรงดันหน่วยความจำ ทริกเกอร์โดยไม่จำเป็น ให้เพิ่มค่านี้เพื่อทำให้อุปกรณ์ มีความไวน้อยลงต่อสัญญาณรบกวน | 70 |
200 |
ro.lmk.psi_complete_stall_ms |
เกณฑ์การหยุดทำงานของ PSI ที่สมบูรณ์เป็นมิลลิวินาทีสำหรับการทริกเกอร์ การแจ้งเตือนหน่วยความจำที่สำคัญ หากอุปกรณ์ได้รับการแจ้งเตือนแรงดันหน่วยความจำที่สำคัญช้าเกินไป ให้ลดค่านี้เพื่อทริกเกอร์การแจ้งเตือนก่อนหน้านี้ หากการแจ้งเตือนหน่วยความจำเหลือน้อยที่สำคัญทริกเกอร์โดยไม่จำเป็น ให้เพิ่มค่านี้เพื่อลดความไวของอุปกรณ์ต่อสัญญาณรบกวน | 700 |
|
ro.lmk.thrashing_limit |
จำนวนสูงสุดของ WorkingSet Refaults เป็นเปอร์เซ็นต์ของขนาด PageCache ที่มีไฟล์สำรองทั้งหมด การเปลี่ยนเส้นทางของชุดการทำงานที่สูงกว่าค่านี้หมายความว่า ระบบถือว่ากำลังสลับแคชหน้าเว็บ หาก ประสิทธิภาพของอุปกรณ์ได้รับผลกระทบระหว่างการใช้หน่วยความจำอย่างหนัก ให้ลด ค่าเพื่อจำกัดการสลับหน่วยความจำ หากประสิทธิภาพของอุปกรณ์ลดลง โดยไม่จำเป็นเนื่องจากเหตุผลในการสลับหน้า ให้เพิ่มค่าเพื่ออนุญาตการ สลับหน้ามากขึ้น | 100 |
30 |
ro.lmk.thrashing_limit_decay |
การลดเกณฑ์การเกิด Thrashing ที่แสดงเป็นเปอร์เซ็นต์ของ เกณฑ์เดิมที่ใช้ลดเกณฑ์เมื่อระบบไม่ กู้คืน แม้หลังจากหยุดการทำงานแล้วก็ตาม หากการสลับอย่างต่อเนื่องทำให้เกิดการสิ้นสุดกระบวนการที่ไม่จำเป็น ให้ลดค่าลง หากการตอบสนองต่อการกระหน่ำอย่างต่อเนื่องหลังจาก การหยุดทำงานช้าเกินไป ให้เพิ่มค่า | 10 |
50 |
ro.lmk.swap_util_max |
จำนวนหน่วยความจำที่สลับสูงสุดเป็นเปอร์เซ็นต์ของหน่วยความจำทั้งหมดที่สลับได้
เมื่อหน่วยความจำที่สลับมีขนาดเกินขีดจำกัดนี้ แสดงว่า
ระบบได้สลับหน่วยความจำที่สลับได้ส่วนใหญ่แล้วและยังคงมีภาระหนักอยู่
กรณีนี้อาจเกิดขึ้นเมื่อการจัดสรรที่สลับไม่ได้สร้างแรงกดดันด้านหน่วยความจำ
ซึ่งไม่สามารถลดลงได้ด้วยการสลับเนื่องจากหน่วยความจำที่สลับได้ส่วนใหญ่
ถูกสลับออกไปแล้ว ค่าเริ่มต้นคือ 100 ซึ่งจะปิดใช้การตรวจสอบนี้ หากประสิทธิภาพของอุปกรณ์ได้รับผลกระทบระหว่าง
หน่วยความจำเต็มขณะที่การใช้พื้นที่สวอปสูงและระดับพื้นที่สวอปที่ว่าง
ไม่ลดลงเหลือ ro.lmk.swap_free_low_percentage ให้ลด
ค่าเพื่อจำกัดการใช้พื้นที่สวอป |
100 |
100 |
ปุ่มปรับแต่งเดิมต่อไปนี้ยังใช้ได้กับกลยุทธ์การหยุดทำงานใหม่ด้วย
พร็อพเพอร์ตี้ | ใช้ | ค่าเริ่มต้น | |
---|---|---|---|
ประสิทธิภาพสูง | RAM น้อย | ||
ro.lmk.swap_free_low_percentage |
ระดับของพื้นที่แลกเปลี่ยนข้อมูลว่างเป็นเปอร์เซ็นต์ของพื้นที่แลกเปลี่ยนข้อมูลทั้งหมด `lmkd` ใช้ค่านี้เป็นเกณฑ์ในการพิจารณาว่าระบบมีพื้นที่สวอป ไม่เพียงพอเมื่อใด หาก `lmkd` หยุดทำงานขณะที่มีพื้นที่ใน Swap มากเกินไป ให้ลดเปอร์เซ็นต์ หาก `lmkd` ฆ่าช้าเกินไปจนทำให้เกิดการฆ่า OOM ให้เพิ่มเปอร์เซ็นต์ | 20 |
10 |
ro.lmk.debug |
ซึ่งจะเปิดใช้บันทึกการแก้ไขข้อบกพร่องของ `lmkd` เปิดใช้การแก้ไขข้อบกพร่องขณะปรับ | false |