การเพิ่มประสิทธิภาพหน่วยความจำเป็นสิ่งสำคัญอย่างยิ่งต่อการมอบประสบการณ์การเล่นเกมที่มีเสถียรภาพและมีประสิทธิภาพสูงใน Android คู่มือนี้จะให้ภาพรวมเกี่ยวกับความสำคัญของประสิทธิภาพการใช้หน่วยความจำ วิธีที่ระบบปฏิบัติการ Android จัดการและบังคับใช้ขีดจำกัดหน่วยความจำของกระบวนการ รวมถึงเกณฑ์ใหม่ที่แสดงใน Google Play Console เพื่อช่วยคุณตรวจสอบและปรับปรุงคุณภาพทางเทคนิคของเกม
ความสำคัญของการเพิ่มประสิทธิภาพหน่วยความจำ
การเพิ่มประสิทธิภาพหน่วยความจำของเกมเป็นสิ่งสำคัญในการรักษาผู้เล่นไว้ ขยายความเข้ากันได้ของอุปกรณ์ และปฏิบัติตามมาตรฐานคุณภาพของแพลตฟอร์ม
- การป้องกัน Cold Start (ประสบการณ์ของผู้ใช้และการรักษาผู้ใช้ไว้): เมื่อผู้เล่นเปลี่ยนไปใช้แอปอื่นชั่วคราว (เช่น เพื่อตอบการแจ้งเตือนหรือตรวจสอบข้อความ) ระบบปฏิบัติการจะย้ายกระบวนการของเกมไปทำงานเบื้องหลัง หากหน่วยความจำที่ใช้เบื้องหลังของเกมสูงเกินไป Low Memory Killer (LMK) ของระบบจะจัดลำดับความสำคัญในการสิ้นสุดกระบวนการของเกมเพื่อเรียกคืน RAM สำหรับงานที่ทำงานอยู่เบื้องหน้า เมื่อผู้ใช้กลับมาเล่นเกมอีกครั้ง แทนที่จะเป็นการกลับมาทำงานต่อแบบอุ่นเครื่องที่ราบรื่นและรวดเร็ว เกมจะต้องผ่านการเริ่มต้นแบบ Cold Start ที่ใช้เวลานาน ซึ่งจะโหลดซ้ำอย่างสมบูรณ์ทั้งทรัพยากรกราฟิกขนาดใหญ่ เสียง และไบนารีของเกมเอนจินจากพื้นที่เก็บข้อมูล การรักษาการใช้งานหน่วยความจำเบื้องหลังให้ต่ำจะช่วยป้องกันการสิ้นสุดการทำงานเบื้องหลังแบบเงียบๆ เหล่านี้ ซึ่งจะช่วยรักษาสถานะของผู้ใช้และทำให้ผู้เล่นกลับมาเล่นเกมต่อได้ทันที ดูรายละเอียดเพิ่มเติมเกี่ยวกับลักษณะการทำงานของ LMK ของระบบได้ที่คู่มือ Android Vitals - Low memory killers
- เสถียรภาพของระบบนิเวศและอุปกรณ์: การใช้หน่วยความจำอย่างไม่มีประสิทธิภาพและการรั่วไหลของหน่วยความจำ จะทำให้ประสิทธิภาพโดยรวมของระบบลดลง เมื่อหน่วยความจำของระบบมีไม่เพียงพอ ระบบจะได้รับแรงกดดันอย่างมาก ส่งผลให้เฟรมเรตลดลง UI กระตุก และเสียงผิดเพี้ยน หากแรงกดดันด้านหน่วยความจำรุนแรงเกินไป Low Memory Killer (LMK) ของระบบจะสิ้นสุดกระบวนการเบื้องหลังอย่างรุนแรง ทำให้แอปพลิเคชันอื่นๆ ต้องผ่านการเริ่มต้นแบบเย็นที่ช้าและสูญเสียสถานะของผู้ใช้เมื่อผู้เล่นสลับไปทำงานอื่น
- การสิ้นสุดการทำงานระดับแพลตฟอร์ม: ตั้งแต่ Android 17 (ระดับ API 37) เป็นต้นไป ระบบจะทำงานเชิงรุกมากขึ้นในการสิ้นสุดกระบวนการที่ใช้หน่วยความจำมากเกินไป หากการใช้หน่วยความจำของเกมสูงเกินไป ระบบปฏิบัติการอาจสิ้นสุดกระบวนการของเกมอย่างกะทันหันโดยไม่สร้างสแต็กเทรซมาตรฐาน
- ความเข้ากันได้ของอุปกรณ์: แม้ว่าอุปกรณ์รุ่นเรือธงจะมี RAM ขนาด 12 GB ถึง 16 GB แต่ผู้เล่นเกมทั่วโลกจำนวนมากใช้อุปกรณ์ที่มี RAM ขนาด 4 GB หรือ 6 GB การจัดการหน่วยความจำอย่างเหมาะสมจะช่วยให้เกมยังคงเข้าถึงได้และตอบสนองได้ดีในฮาร์ดแวร์ทุกระดับโดยไม่ต้องใช้แพ็กเกจชิ้นงานที่ซับซ้อนและแยกกัน
ทำความเข้าใจหน่วยความจำใน Android
นักพัฒนาแอปต้องเข้าใจวิธีที่แพลตฟอร์ม Android จัดการหน่วยความจำจริงและวิธีวัดการใช้หน่วยความจำที่ใช้งานอยู่ของเกม เพื่อออกแบบกลยุทธ์การจัดสรรหน่วยความจำที่มีประสิทธิภาพ
แนวคิดหลักเกี่ยวกับหน่วยความจำของ Android
ดูแนวคิดพื้นฐานเกี่ยวกับการจัดการหน่วยความจำระดับแพลตฟอร์มได้ในเอกสารประกอบ ภาพรวมการจัดการหน่วยความจำอย่างเป็นทางการ แหล่งข้อมูลนี้ครอบคลุม 4 ส่วนของสถาปัตยกรรม ได้แก่
- ภาพรวมหน่วยความจำ: Android ใช้การเพจและการแมปหน่วยความจำ (mmap) เพื่อจัดการ RAM ระบบไม่รองรับไฟล์ Swap แบบเดิมในดิสก์ แต่จะใช้การบีบอัดเพจ (โดยใช้ zRAM) และการเรียกคืนเพจเพื่อเพิ่มหน่วยความจำจริง
- การจัดสรรหน่วยความจำระหว่างกระบวนการ: Android แชร์ RAM ทั่วทั้ง ระบบ ระบบจะกำหนดฮีปที่เฉพาะเจาะจงสำหรับการดำเนินการเครื่องเสมือน Dalvik หรือ ART ขณะเดียวกันก็อนุญาตให้สภาพแวดล้อมการพัฒนาแบบเนทีฟ (เช่น เอนจินเกม C++) ขอหน่วยความจำจากฮีปของระบบแบบเนทีฟ
- การจัดการหน่วยความจำของแอป: Android ทำงานภายใต้โมเดลแบบหลายกระบวนการ โดย คาดหวังให้แอปพลิเคชันตรวจสอบสถานะวงจรชีวิตของตนเองแบบไดนามิกและ ปล่อยทรัพยากรที่ไม่จำเป็น (เช่น กราฟิกและ บิตแมปที่ไม่ได้แคช) โดยสมัครใจเพื่อสนับสนุนประสิทธิภาพของระบบ
- ภาพรวมกระบวนการและเธรด: ระบบจะจัดหมวดหมู่กระบวนการเป็น ลำดับชั้นตามการมองเห็นและความสำคัญที่ผู้ใช้รับรู้ในปัจจุบัน ซึ่งจะเป็นตัวกำหนดว่ากระบวนการใดจะทำงานต่อไปและกระบวนการใดจะสิ้นสุดก่อน ในสภาวะที่หน่วยความจำเหลือน้อย
เมตริกหน่วยความจำที่ใช้ทั้งหมด
Memory Limiter ของ Android 17 ระดับแพลตฟอร์มจะประเมินการใช้หน่วยความจำของกระบวนการโดยใช้การใช้หน่วยความจำทั้งหมด แทนที่จะใช้ขนาดหน่วยความจำที่ใช้งานอยู่ทั้งหมด (RSS) หรือขนาดหน่วยความจำเสมือน
การใช้หน่วยความจำทั้งหมด = RSS แบบไม่ระบุชื่อ (RssAnon) + Swap ที่ไม่ได้บีบอัด (VmSwap)
นักพัฒนาแอปต้องเข้าใจอย่างชัดเจนว่าเมตริกเหล่านี้แสดงถึงอะไรในระดับระบบ เพื่อป้องกันไม่ให้เกมใช้หน่วยความจำเกินขีดจำกัดที่แพลตฟอร์มกำหนด ดูข้อมูลเพิ่มเติมเกี่ยวกับเมตริกเหล่านี้ การจัดสรร RAM จริง และวิธีจัดการเพจที่สำรองข้อมูลไว้ในไฟล์ได้ที่หัวข้อ ทำความเข้าใจเมตริก RSS และ Swap ในคู่มือตรวจสอบ การใช้หน่วยความจำ
ข้อจำกัดด้านหน่วยความจำ
แพลตฟอร์ม Android จะบังคับใช้ขีดจำกัดหน่วยความจำกับกระบวนการที่ทำงานอยู่ เพื่อรักษาเสถียรภาพของระบบและป้องกันไม่ให้แอปพลิเคชันใช้ทรัพยากรมากเกินไป
Memory Limiter ใน Android 17 ขึ้นไป
Android 17 ขึ้นไปจะบังคับใช้ขีดจำกัดหน่วยความจำที่เข้มงวดต่อแอปโดยใช้ cgroup v2 ของ Linux เพื่อป้องกันไม่ให้แอปแต่ละแอปทำให้ระบบโดยรวมไม่เสถียร ดูรายละเอียดเพิ่มเติมเกี่ยวกับการใช้งานทางเทคนิคได้ที่ คู่มือ Memory Limiter ของ AOSP และบล็อกการให้ความสำคัญกับประสิทธิภาพการใช้หน่วยความจำ: ขั้นตอนสำคัญสำหรับ Android 17
- กลไก: Memory Limiter จะตรวจสอบกระบวนการของแอปพลิเคชันทั้งหมดและ
กำหนดขีดจำกัดแบบไดนามิกตามสถานะวงจรชีวิตของกระบวนการ ดังนี้
- กระบวนการที่มองเห็นได้ (เบื้องหน้า): กระบวนการของแอปที่แสดง UI อยู่ในปัจจุบันคาดว่าจะใช้ชุดทรัพยากรที่ทำงานอยู่ขนาดใหญ่กว่า และจะได้รับ ขีดจำกัดที่สูงกว่า
- กระบวนการที่มองไม่เห็น (เบื้องหลังหรือบริการ): กระบวนการของแอปที่ทำงานอยู่โดยไม่แสดง UI จะถูกจำกัดให้ใช้ทรัพยากรน้อยลงและเข้มงวดมากขึ้น
- แอตทริบิวต์เคอร์เนล: บริการนี้ใช้แอตทริบิวต์หลัก 2 รายการ ได้แก่
memory.high: ขีดจำกัดแบบยืดหยุ่น เมื่อใช้เกินขีดจำกัด เคอร์เนลจะควบคุมกระบวนการและพยายามเรียกคืนหน่วยความจำอย่างรุนแรง การเรียกคืนนี้อาจทำให้ประสิทธิภาพของเกมลดลงmemory.swap.max: บังคับใช้ขีดจำกัดสูงสุดแบบเข้มงวดกับพื้นที่ Swap หรือ zRAM ที่กระบวนการใช้ได้
- ลักษณะการทำงานของการสิ้นสุด: หากกระบวนการยังคงจัดสรรหน่วยความจำแบบไม่ระบุชื่อ
เกิน
memory.highและใช้ความจุ Swap จนหมด การจัดสรรจะล้มเหลว และระบบปฏิบัติการจะสิ้นสุดกระบวนการอย่างเงียบๆ ระบบจะบันทึกการสิ้นสุดนี้โดยใช้ApplicationExitInfoภายใต้เหตุผลการสิ้นสุดของ Memory Limiter (พร้อมใช้งานตั้งแต่ Android 17, 26Q4)
ตรวจสอบการใช้งานหน่วยความจำ
คุณต้องเข้าใจวิธีที่แพลตฟอร์ม Android วัดการใช้หน่วยความจำของเกมก่อนจึงจะเพิ่มประสิทธิภาพหน่วยความจำของเกมได้อย่างมีประสิทธิภาพ Android 17 อัปเดตเมตริกการบังคับใช้หน่วยความจำเพื่อติดตามผลรวมของ RSS แบบไม่ระบุชื่อ (RssAnon) และ Swap ที่ไม่ได้บีบอัด (VmSwap) โดยไม่รวมหน่วยความจำที่สำรองข้อมูลไว้ในไฟล์หรือหน่วยความจำส่วนตัวของ GPU คู่มือนี้จะอธิบายรายละเอียดเกี่ยวกับวิธีใช้ประโยชน์จากเครื่องมือระดับระบบ เช่น Perfetto และ meminfo รวมถึงวิธีใช้ API การวินิจฉัย เช่น ProfilingManager และ onTrimMemory และวิธีแยกการจัดสรรหน่วยความจำที่แม่นยำภายใน Unity และ Unreal Engine ทำความเข้าใจวิธีสร้างโปรไฟล์เกมอย่างถูกต้องและหลีกเลี่ยงการกระตุกแบบข้ามเฟรมของประสิทธิภาพที่เกี่ยวข้องกับการโพลหน่วยความจำรันไทม์แบบดั้งเดิม
ดูข้อมูลเพิ่มเติมได้ที่หัวข้อตรวจสอบการใช้หน่วยความจำ
กลยุทธ์การลดหน่วยความจำ
แม้ว่าเอนจินเกมจะช่วยลดความซับซ้อนในการพัฒนาข้ามแพลตฟอร์ม แต่การจัดการหน่วยความจำเริ่มต้นของเอนจินอาจทำให้เกิดขีดจำกัดหน่วยความจำระดับระบบปฏิบัติการได้ หน้านี้จะอธิบายรายละเอียดเกี่ยวกับขั้นตอนการเพิ่มประสิทธิภาพที่ใช้งานได้จริงซึ่งปรับแต่งมาสำหรับ Unity และ Unreal Engine โดยเฉพาะ ทำความเข้าใจว่าการใช้ onTrimMemory ที่อิงตาม Java อาจทำให้เกิดการล็อกตายใน Unity ได้อย่างไร และวิธีใช้การเรียกกลับวงจรชีวิตแบบเนทีฟแทน นอกจากนี้ คุณจะได้พบกับการเพิ่มประสิทธิภาพระดับชิ้นงานที่สำคัญ เช่น การใช้การบีบอัดเท็กซ์เจอร์ ASTC 8x8 และการกำหนดค่าการยกเลิกการโหลดชิ้นงาน เพื่อให้เกมทำงานได้อย่างราบรื่นในฮาร์ดแวร์ทุกระดับ