เกี่ยวกับการจัดการหน่วยความจำ

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