การเพิ่มประสิทธิภาพหน่วยความจำเป็นสิ่งสำคัญอย่างยิ่งต่อการมอบประสบการณ์การเล่นเกมที่มีเสถียรภาพและมีประสิทธิภาพสูงใน 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 (ระดับ API 37) ขึ้นไปจะจัดการขีดจำกัดหน่วยความจำที่เข้มงวดต่อแอปโดยใช้ 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 และการกำหนดค่าการยกเลิกการโหลดองค์ประกอบ เพื่อให้เกมทำงานได้อย่างราบรื่นในทุกระดับฮาร์ดแวร์