แพลตฟอร์ม Android ทำงานโดยมีสมมติฐานว่าหน่วยความจำที่ว่างอยู่คือหน่วยความจำที่สูญเปล่า ระบบจึงพยายามใช้หน่วยความจำทั้งหมดที่มีอยู่ตลอดเวลา ตัวอย่างเช่น ระบบจะเก็บแอปไว้ในหน่วยความจำหลังจากที่ปิดแอปแล้วเพื่อให้ผู้ใช้กลับไปใช้แอปได้อย่างรวดเร็ว ด้วยเหตุนี้ อุปกรณ์ Android จึงมักทำงานโดยมีหน่วยความจำที่ว่างเหลือน้อยมาก การจัดการหน่วยความจำจึงมีความสำคัญอย่างยิ่งในการจัดสรรหน่วยความจำอย่างเหมาะสมระหว่างกระบวนการของระบบที่สำคัญและแอปพลิเคชันของผู้ใช้จำนวนมาก
หน้านี้จะอธิบายข้อมูลพื้นฐานเกี่ยวกับวิธีที่ Android จัดสรรหน่วยความจำให้กับระบบและแอปพลิเคชันของผู้ใช้ รวมถึงอธิบายวิธีที่ระบบปฏิบัติการตอบสนองต่อสถานการณ์ที่หน่วยความจำเหลือน้อย
ประเภทของหน่วยความจำ
อุปกรณ์ Android มีหน่วยความจำ 3 ประเภท ได้แก่ RAM, zRAM และพื้นที่เก็บข้อมูล โปรดทราบว่าทั้ง CPU และ GPU เข้าถึง RAM เดียวกัน
รูปที่ 1 ประเภทของหน่วยความจำ - RAM, zRAM และพื้นที่เก็บข้อมูล
RAM เป็นหน่วยความจำประเภทที่เร็วที่สุด แต่โดยปกติจะมีขนาดจำกัด อุปกรณ์ระดับไฮเอนด์มักจะมี RAM มากที่สุด
zRAM คือพาร์ติชันของ RAM ที่ใช้สำหรับพื้นที่สวอป ระบบจะบีบอัดทุกอย่างเมื่อวางลงใน zRAM แล้วคลายการบีบอัดเมื่อคัดลอกจาก zRAM RAM ส่วนนี้จะมีขนาดเพิ่มขึ้นหรือลดลงเมื่อมีการย้ายหน้าเข้าหรือออกจาก zRAM ผู้ผลิตอุปกรณ์สามารถกำหนดขนาดสูงสุดได้
พื้นที่เก็บข้อมูลมีข้อมูลถาวรทั้งหมด เช่น ระบบไฟล์และโค้ดออบเจ็กต์ที่รวมไว้สำหรับแอป ไลบรารี และแพลตฟอร์มทั้งหมด พื้นที่เก็บข้อมูลมีความจุมากกว่าหน่วยความจำอีก 2 ประเภทมาก ใน Android ระบบจะไม่ใช้พื้นที่เก็บข้อมูลสำหรับพื้นที่สวอปเหมือนกับการใช้งาน Linux อื่นๆ เนื่องจากมีการเขียนข้อมูลบ่อยๆ อาจทำให้หน่วยความจำนี้เสื่อมสภาพและทำให้อายุการใช้งานของสื่อบันทึกลดลง
หน้าหน่วยความจำ
RAM จะแบ่งออกเป็น หน้า โดยปกติแล้วแต่ละหน้าจะมีหน่วยความจำ 4KB
หน้าจะถือว่าเป็น ว่าง หรือ ใช้งาน หน้าว่างคือ RAM ที่ไม่ได้ใช้ หน้าใช้งานคือ RAM ที่ระบบกำลังใช้งานอยู่ และจะจัดกลุ่มเป็นหมวดหมู่ต่อไปนี้
- แคช: หน่วยความจำที่สำรองด้วยไฟล์ในพื้นที่เก็บข้อมูล (เช่น โค้ดหรือไฟล์ที่แมปกับหน่วยความจำ) หน่วยความจำแคชมี 2 ประเภท ได้แก่
- ส่วนตัว: เป็นของกระบวนการเดียวและไม่ได้แชร์
- สะอาด: สำเนาไฟล์ที่ไม่ได้แก้ไขในพื้นที่เก็บข้อมูล ซึ่ง
kswapdสามารถลบได้เพื่อเพิ่มหน่วยความจำที่ว่าง - มีการแก้ไข: สำเนาไฟล์ที่แก้ไขแล้วในพื้นที่เก็บข้อมูล ซึ่ง
kswapdสามารถย้ายไปหรือบีบอัดใน zRAM ได้เพื่อเพิ่มหน่วยความจำที่ว่าง
- สะอาด: สำเนาไฟล์ที่ไม่ได้แก้ไขในพื้นที่เก็บข้อมูล ซึ่ง
- แชร์: ใช้โดยหลายกระบวนการ
- ส่วนตัว: เป็นของกระบวนการเดียวและไม่ได้แชร์
- ไม่ระบุชื่อ: หน่วยความจำที่ไม่ได้ สำรองด้วยไฟล์ในพื้นที่เก็บข้อมูล (เช่น
จัดสรรโดย
mmap()โดยตั้งค่าแฟล็กMAP_ANONYMOUS)- สกปรก:
kswapdสามารถย้าย/บีบอัดใน zRAM ได้เพื่อเพิ่มหน่วยความจำที่ว่าง
- สกปรก:
สัดส่วนของหน้าว่างและหน้าใช้งานจะแตกต่างกันไปตามเวลาเนื่องจากระบบจัดการ RAM อย่างต่อเนื่อง แนวคิดที่แนะนำในส่วนนี้มีความสำคัญต่อการจัดการสถานการณ์ที่หน่วยความจำเหลือน้อย ส่วนถัดไปของเอกสารนี้จะอธิบายแนวคิดเหล่านี้โดยละเอียดมากขึ้น
การจัดการหน่วยความจำเหลือน้อย
Android มีกลไกหลัก 2 อย่างในการจัดการสถานการณ์ที่หน่วยความจำเหลือน้อย ได้แก่ เคอร์เนลสวอปดีมอนและตัวจัดการกระบวนการเมื่อหน่วยความจำเหลือน้อย
เคอร์เนลสวอปดีมอน
เคอร์เนลสวอปดีมอน (kswapd) เป็นส่วนหนึ่งของเคอร์เนล Linux และจะแปลงหน่วยความจำที่ใช้แล้วเป็นหน่วยความจำที่ว่าง Daemon จะทำงานเมื่อหน่วยความจำที่ว่างในอุปกรณ์เหลือน้อย เคอร์เนล Linux จะรักษาเกณฑ์หน่วยความจำที่ว่างเหลือน้อยและเหลือมาก
เมื่อหน่วยความจำที่ว่างลดลงต่ำกว่าเกณฑ์ต่ำ kswapd จะเริ่มเรียกคืนหน่วยความจำ เมื่อหน่วยความจำที่ว่างถึงเกณฑ์สูง kswapd จะหยุดเรียกคืนหน่วยความจำ
kswapd สามารถเรียกคืนหน้าสะอาดได้โดยการลบหน้าเหล่านั้นเนื่องจากหน้าสะอาดได้รับการสำรองด้วยพื้นที่เก็บข้อมูลและไม่ได้แก้ไข หากกระบวนการพยายามเข้าถึงหน้าสะอาดที่ถูกลบ ระบบจะคัดลอกหน้าจากพื้นที่เก็บข้อมูลไปยัง RAM การดำเนินการนี้เรียกว่า การเพจตามความต้องการ
รูปที่ 2 หน้าสะอาดที่สำรองด้วยพื้นที่เก็บข้อมูลถูกลบ
kswapd สามารถย้ายหน้าที่มีการแก้ไขแคชส่วนตัวและหน้าที่มีการแก้ไขที่ไม่ระบุชื่อไปยัง zRAM ซึ่งจะมีการบีบอัดหน้าเหล่านั้น การดำเนินการดังกล่าวจะเพิ่มหน่วยความจำที่ว่างใน RAM (หน้าว่าง) หากกระบวนการพยายามเข้าถึงหน้าที่มีการแก้ไขใน zRAM ระบบจะคลายการบีบอัดหน้าและย้ายกลับไปที่ RAM หากกระบวนการที่เชื่อมโยงกับหน้าบีบอัดถูกหยุด ระบบจะลบหน้าออกจาก zRAM
หากหน่วยความจำที่ว่างลดลงต่ำกว่าเกณฑ์ที่กำหนด ระบบจะเริ่มหยุดกระบวนการ
รูปที่ 3 หน้าที่มีการแก้ไขถูกย้ายไปยัง zRAM และบีบอัด
ตัวจัดการกระบวนการเมื่อหน่วยความจำเหลือน้อย
หลายครั้งที่ kswapd ไม่สามารถเพิ่มหน่วยความจำที่ว่างให้ระบบได้เพียงพอ ในกรณีนี้ ระบบจะใช้
onTrimMemory()
เพื่อแจ้งให้แอปทราบว่าหน่วยความจำเหลือน้อยและแอปควรลดการจัดสรร
หากยังไม่เพียงพอ เคอร์เนลจะเริ่มหยุดกระบวนการเพื่อเพิ่มหน่วยความจำที่ว่าง โดยจะใช้ตัวจัดการกระบวนการเมื่อหน่วยความจำเหลือน้อย (LMK) ในการดำเนินการนี้
LMK จะใช้คะแนน "หน่วยความจำไม่พอ" ที่เรียกว่า
oom_adj_score
เพื่อจัดลำดับความสำคัญของกระบวนการที่กำลังทำงานอยู่ในการตัดสินใจว่าจะหยุดกระบวนการใด กระบวนการที่มีคะแนนสูงจะถูกหยุดก่อน แอปที่ทำงานอยู่เบื้องหลังจะถูกหยุดก่อน และกระบวนการของระบบจะถูกหยุดเป็นลำดับสุดท้าย ตารางต่อไปนี้แสดงหมวดหมู่การให้คะแนน LMK จากสูงไปต่ำ รายการในหมวดหมู่ที่มีคะแนนสูงสุดในแถวแรกจะถูกหยุดก่อน
รูปที่ 4 กระบวนการของ Android โดยมีคะแนนสูงอยู่ด้านบนและคะแนนต่ำอยู่ด้านล่าง
คำอธิบายสำหรับหมวดหมู่ต่างๆ ในตารางด้านบนมีดังนี้
แอปที่ทำงานอยู่เบื้องหลัง: แอปที่เคยทำงานและไม่ได้ใช้งานอยู่ในปัจจุบัน LMK จะหยุดแอปที่ทำงานอยู่เบื้องหลังก่อน โดยเริ่มจากแอปที่มี
oom_adj_scoreสูงที่สุดแอปก่อนหน้า: แอปที่ทำงานอยู่เบื้องหลังซึ่งใช้ล่าสุด แอปก่อนหน้ามีความสำคัญสูงกว่า (คะแนนต่ำกว่า) แอปที่ทำงานอยู่เบื้องหลัง เนื่องจากผู้ใช้มีแนวโน้มที่จะสลับไปใช้แอปก่อนหน้ามากกว่าแอปที่ทำงานอยู่เบื้องหลัง
แอป Home: นี่คือแอปตัวเรียกใช้ การหยุดแอปนี้จะทำให้วอลเปเปอร์หายไป
บริการ: แอปพลิเคชันจะเริ่มบริการ และบริการอาจรวมถึงการซิงค์หรือการอัปโหลดไปยังระบบคลาวด์
แอปที่รับรู้ได้: แอปที่ไม่ได้ทำงานอยู่เบื้องหน้าซึ่งผู้ใช้รับรู้ได้ในบางวิธี เช่น การเรียกใช้กระบวนการค้นหาที่แสดง UI ขนาดเล็กหรือการฟังเพลง
แอปที่ทำงานอยู่เบื้องหน้า: แอปที่กำลังใช้งานอยู่ การหยุดแอปที่ทำงานอยู่เบื้องหน้าจะมีลักษณะเหมือนแอปพลิเคชันขัดข้อง ซึ่งอาจบ่งบอกให้ผู้ใช้ทราบว่ามีบางอย่างผิดปกติกับอุปกรณ์
ถาวร (บริการ): บริการเหล่านี้เป็นบริการหลักสำหรับอุปกรณ์ เช่น โทรศัพท์และ Wi-Fi
ระบบ: กระบวนการของระบบ เมื่อกระบวนการเหล่านี้ถูกหยุด โทรศัพท์อาจปรากฏขึ้นเพื่อรีบูต
เนทีฟ: กระบวนการระดับต่ำมากที่ระบบใช้ (เช่น
kswapd)
ผู้ผลิตอุปกรณ์สามารถเปลี่ยนลักษณะการทำงานของ LMK ได้
การคำนวณหน่วยความจำที่ใช้
เคอร์เนลจะติดตามหน้าหน่วยความจำทั้งหมดในระบบ
รูปที่ 5 หน้าต่างๆ ที่กระบวนการต่างๆ ใช้
เมื่อพิจารณาว่าแอปใช้หน่วยความจำเท่าใด ระบบจะต้องคำนึงถึงหน้าแชร์ แอปที่เข้าถึงบริการหรือไลบรารีเดียวกันจะแชร์หน้าหน่วยความจำ ตัวอย่างเช่น บริการ Google Play และแอปเกมอาจแชร์บริการตำแหน่ง ซึ่งทำให้ยากต่อการระบุว่าหน่วยความจำจำนวนเท่าใดเป็นของบริการโดยรวมเทียบกับแอปพลิเคชันแต่ละรายการ
รูปที่ 6 หน้าต่างๆ ที่แชร์โดยแอป 2 แอป (ตรงกลาง)
ระบบอาจใช้เมตริกใดเมตริกหนึ่งต่อไปนี้เพื่อกำหนดหน่วยความจำที่ใช้สำหรับแอปพลิเคชัน
- ขนาดชุดที่อยู่ในหน่วยความจำ (RSS): จำนวนหน้าแชร์และหน้าที่ไม่แชร์ที่แอปใช้
- ขนาดชุดตามสัดส่วน (PSS): จำนวนหน้าที่ไม่แชร์ที่แอปใช้และการกระจายหน้าแชร์อย่างเท่าเทียมกัน (เช่น หาก 3 กระบวนการแชร์ 3MB แต่ละกระบวนการจะได้รับ 1MB ใน PSS)
- ขนาดชุดที่ไม่ซ้ำกัน (USS): จำนวนหน้าที่ไม่แชร์ที่แอปใช้ (ไม่รวมหน้าแชร์)
PSS มีประโยชน์สำหรับระบบปฏิบัติการเมื่อต้องการทราบว่ากระบวนการทั้งหมดใช้หน่วยความจำเท่าใด เนื่องจากระบบจะไม่นับหน้าซ้ำ PSS ใช้เวลานานในการคำนวณเนื่องจากระบบต้องพิจารณาว่าหน้าใดแชร์และแชร์โดยกระบวนการจำนวนเท่าใด RSS ไม่ได้แยกความแตกต่างระหว่างหน้าแชร์และหน้าที่ไม่แชร์ (จึงคำนวณได้เร็วกว่า) และเหมาะกว่าสำหรับการติดตามการเปลี่ยนแปลงในการจัดสรรหน่วยความจำ
แหล่งข้อมูลเพิ่มเติม
- ภาพรวมของการจัดการหน่วยความจำ
- กระบวนการและวงจรชีวิตของแอปพลิเคชัน
- ทำความเข้าใจการใช้งานหน่วยความจำของ Android - งานนำเสนอใน Google I/O
- หน่วยความจำและเกมของ Android - งานนำเสนอใน Google I/O
- ดีมอนตัวจัดการกระบวนการเมื่อหน่วยความจำเหลือน้อยของ Android
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- เวลาเริ่มต้นของแอป