กระบวนการ Daemon ของตัวจัดการการหยุดทำงานเนื่องจากหน่วยความจำไม่เพียงพอ (lmkd) ของ Android จะตรวจสอบสถานะหน่วยความจำของระบบ Android ที่ทำงานอยู่ และตอบสนองต่อการใช้หน่วยความจำสูงด้วยการหยุดกระบวนการที่ไม่จำเป็นที่สุดเพื่อให้ระบบทำงานในระดับที่ยอมรับได้
เกี่ยวกับการใช้หน่วยความจำ
ระบบ Android ที่เรียกใช้กระบวนการหลายรายการแบบขนานอาจพบสถานการณ์ที่หน่วยความจำของระบบหมดและกระบวนการที่ต้องใช้หน่วยความจำมากขึ้นเกิดความล่าช้าอย่างเห็นได้ชัด การใช้หน่วยความจำ ซึ่งเป็นสถานะที่ ระบบมีหน่วยความจำไม่เพียงพอ ทำให้ Android ต้องเพิ่มหน่วยความจำ (เพื่อลด การใช้หน่วยความจำ) โดยการควบคุมหรือหยุดกระบวนการที่ไม่สำคัญ ขอให้ กระบวนการเพิ่มทรัพยากรที่แคชไว้ซึ่งไม่สำคัญ และอื่นๆ
ในอดีต Android ตรวจสอบการใช้หน่วยความจำของระบบโดยใช้ไดรเวอร์ตัวจัดการการหยุดทำงานเนื่องจากหน่วยความจำไม่เพียงพอ (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 ต่ำต้องได้รับการปรับแต่งอย่างเข้มงวด และถึงอย่างนั้นก็ยังทำงานได้ไม่ดีในปริมาณงานที่มีแคชหน้าเว็บที่ใช้งานอยู่ซึ่งมีขนาดใหญ่ ประสิทธิภาพที่ไม่ดีส่งผลให้เกิดการ Thrash และไม่มีการหยุดทำงาน
- ไดรเวอร์ LMK เคอร์เนลอาศัยขีดจำกัดหน่วยความจำที่ว่าง โดยไม่มีการปรับขนาดตามการใช้หน่วยความจำ
- เนื่องจากการออกแบบที่เข้มงวด พาร์ทเนอร์จึงมักจะปรับแต่งไดรเวอร์เพื่อให้ทำงานในอุปกรณ์ของตนได้
- ไดรเวอร์ LMK เชื่อมต่อกับ API ของตัวลดขนาด Slab ซึ่งไม่ได้ออกแบบมาสำหรับการดำเนินการที่หนักหน่วง เช่น การค้นหาเป้าหมายและการหยุดเป้าหมาย ซึ่งทำให้กระบวนการ
vmscanช้าลง
lmkd ในพื้นที่ของผู้ใช้
lmkd ในพื้นที่ของผู้ใช้จะใช้ฟังก์ชันการทำงานเดียวกันกับไดรเวอร์ในเคอร์เนล แต่ใช้กลไกของเคอร์เนลที่มีอยู่เพื่อตรวจหาและประมาณการใช้หน่วยความจำ กลไกดังกล่าวรวมถึงการใช้เหตุการณ์ vmpressure ที่เคอร์เนลสร้างขึ้นหรือจอภาพข้อมูลการหยุดทำงานเนื่องจากการใช้หน่วยความจำ (PSI) เพื่อรับการแจ้งเตือนเกี่ยวกับระดับการใช้หน่วยความจำ และใช้ฟีเจอร์ cgroup ของหน่วยความจำเพื่อจำกัดทรัพยากรหน่วยความจำที่จัดสรรให้กับแต่ละกระบวนการตามความสำคัญของกระบวนการ
ใช้ lmkd ในพื้นที่ของผู้ใช้ใน Android 10
ใน Android 9 ขึ้นไป lmkd ในพื้นที่ของผู้ใช้จะเปิดใช้งานหากไม่พบไดรเวอร์ LMK ในเคอร์เนล เนื่องจาก lmkd ในพื้นที่ของผู้ใช้ต้องได้รับการรองรับจากเคอร์เนลสำหรับ cgroup ของหน่วยความจำ เคอร์เนลจึงต้องคอมไพล์ด้วยการตั้งค่าการกำหนดค่าต่อไปนี้
CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
กลยุทธ์การหยุดทำงาน
lmkd ในพื้นที่ของผู้ใช้รองรับกลยุทธ์การหยุดทำงานตามเหตุการณ์ vmpressure หรือจอภาพ PSI, ความรุนแรง และคำแนะนำอื่นๆ เช่น การใช้ Swap กลยุทธ์การหยุดทำงานจะแตกต่างกันระหว่างอุปกรณ์ที่มีหน่วยความจำต่ำและอุปกรณ์ที่มีประสิทธิภาพสูง
- ในอุปกรณ์ที่มีหน่วยความจำต่ำ ระบบควรยอมรับการใช้หน่วยความจำที่สูงขึ้นเป็นโหมดการทำงานปกติ
- ในอุปกรณ์ที่มีประสิทธิภาพสูง การใช้หน่วยความจำควรถูกมองว่าเป็นสถานการณ์ที่ผิดปกติและแก้ไขก่อนที่จะส่งผลต่อประสิทธิภาพโดยรวม
คุณสามารถกำหนดค่ากลยุทธ์การหยุดทำงานโดยใช้พร็อพเพอร์ตี้ ro.config.low_ram
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` สูงสุดที่ระดับจะได้รับการอัปเกรด
เนื่องจากระบบกำลังสลับมากเกินไปmem_pressure
|
100(ปิดใช้) |
ro.lmk.downgrade_pressure
|
`mem_pressure` ขั้นต่ำที่ระบบจะละเว้นเหตุการณ์ vmpressure
เนื่องจากยังมีหน่วยความจำที่ว่างเพียงพอmem_pressure
|
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 จะพิจารณาระดับการใช้ทรัพยากรหน่วยความจำและการ Thrash เพื่อป้องกันการขาดแคลนหน่วยความจำและประสิทธิภาพลดลง
กลยุทธ์การหยุดทำงานนี้จะแทนที่กลยุทธ์ก่อนหน้าและสามารถใช้ได้กับทั้งอุปกรณ์ที่มีประสิทธิภาพสูงและอุปกรณ์ที่มี 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 |
จำนวนสูงสุดของการเกิดข้อผิดพลาดซ้ำของชุดการทำงานเป็นเปอร์เซ็นต์ของขนาดแคชหน้าเว็บทั้งหมดที่สำรองด้วยไฟล์ การเกิดข้อผิดพลาดซ้ำของชุดการทำงานที่สูงกว่าค่านี้หมายความว่าระบบกำลังสลับหน้าเว็บ หากประสิทธิภาพของอุปกรณ์ได้รับผลกระทบระหว่างการใช้หน่วยความจำ ให้ลดค่าเพื่อจำกัดการ Thrash หากประสิทธิภาพของอุปกรณ์หยุดทำงาน โดยไม่จำเป็นเนื่องจากเหตุผลการ Thrash ให้เพิ่มค่าเพื่อให้มีการ Thrash มากขึ้น | 100 |
30 |
ro.lmk.thrashing_limit_decay |
การลดลงของเกณฑ์การ Thrash แสดงเป็นเปอร์เซ็นต์ของเกณฑ์เดิมที่ใช้เพื่อลดเกณฑ์เมื่อระบบไม่กู้คืน แม้หลังจากหยุดทำงานแล้วก็ตาม หากการ Thrash อย่างต่อเนื่องทำให้เกิดการหยุดทำงานโดยไม่จำเป็น ให้ลดค่า หากการตอบสนองต่อการ Thrash อย่างต่อเนื่องหลังจาก หยุดทำงานช้าเกินไป ให้เพิ่มค่า | 10 |
50 |
ro.lmk.swap_util_max |
หน่วยความจำที่สลับสูงสุดเป็นเปอร์เซ็นต์ของหน่วยความจำทั้งหมดที่สลับได้
เมื่อหน่วยความจำที่สลับเพิ่มขึ้นเกินขีดจำกัดนี้ หมายความว่าระบบได้สลับหน่วยความจำส่วนใหญ่ที่สลับได้และยังคงมีการใช้หน่วยความจำอยู่
กรณีนี้อาจเกิดขึ้นได้เมื่อการจัดสรรที่ไม่สามารถสลับได้ทำให้เกิดการใช้หน่วยความจำ
ซึ่งไม่สามารถลดลงได้โดยการสลับเนื่องจากหน่วยความจำส่วนใหญ่ที่สลับได้ถูกสลับออกไปแล้ว ค่าเริ่มต้นคือ 100 ซึ่งจะปิดใช้การตรวจสอบนี้อย่างมีประสิทธิภาพ
หากประสิทธิภาพของอุปกรณ์ได้รับผลกระทบระหว่าง
การใช้หน่วยความจำในขณะที่การใช้ Swap สูงและระดับ Swap ที่ว่าง
ไม่ลดลงเหลือ ro.lmk.swap_free_low_percentage ให้ลด
ค่าเพื่อจำกัดการใช้ Swap |
100 |
100 |
ปุ่มปรับแต่งเก่าต่อไปนี้ยังทำงานร่วมกับกลยุทธ์การหยุดทำงานใหม่ได้ด้วย
| พร็อพเพอร์ตี้ | ใช้ | ค่าเริ่มต้น | |
|---|---|---|---|
| ประสิทธิภาพสูง | RAM ต่ำ | ||
ro.lmk.swap_free_low_percentage |
ระดับ Swap ที่ว่างเป็นเปอร์เซ็นต์ของพื้นที่ Swap ทั้งหมด `lmkd` ใช้ค่านี้เป็นเกณฑ์ในการพิจารณาว่าระบบมีพื้นที่ Swap ไม่เพียงพอ หาก `lmkd` หยุดทำงานในขณะที่มีพื้นที่ Swap มากเกินไป ให้ลดเปอร์เซ็นต์ หาก `lmkd` หยุดทำงานช้าเกินไป ทำให้เกิดการหยุดทำงานเนื่องจากหน่วยความจำไม่เพียงพอ ให้เพิ่มเปอร์เซ็นต์ | 20 |
10 |
ro.lmk.debug |
การดำเนินการนี้จะเปิดใช้บันทึกการแก้ไขข้อบกพร่อง `lmkd` เปิดใช้การแก้ไขข้อบกพร่องขณะปรับแต่ง | false |
|