การเพิ่มประสิทธิภาพหน่วยความจำเป็นสิ่งสำคัญอย่างยิ่งต่อการมอบประสบการณ์การเล่นเกมที่มีเสถียรภาพและมีประสิทธิภาพสูงใน 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)
ขีดจำกัดหน่วยความจำใหม่ใน Vitals ของ Play Console
Google Play กำลังเปิดตัวเมตริกใหม่ใน Vitals ของ Play Console เพื่อช่วยให้นักพัฒนาแอประบุปัญหาเกี่ยวกับหน่วยความจำได้เชิงรุก Play Console จะติดตามการใช้หน่วยความจำที่ใช้ RSS แบบไม่ระบุตัวตน + Swap เปอร์เซ็นไทล์ที่ 90 (P90) ของเซสชันเกมเพื่อระบุค่าผิดปกติที่รุนแรง
เกณฑ์คำเตือนและการบังคับใช้จะปรับขนาดตามความจุ RAM จริงของอุปกรณ์และสถานะของกระบวนการ ขีดจำกัดเหล่านี้จะมีผลใน 2 ระยะที่แตกต่างกัน
ดูหลักเกณฑ์และขีดจำกัดหน่วยความจำโดยละเอียดได้ที่หัวข้อ Android vitals - "เกณฑ์พฤติกรรมที่ไม่ดีคืออะไร
บริการที่ผู้ใช้รับรู้
บริการที่รับรู้ได้คือกระบวนการเบื้องหลังที่สำคัญซึ่งระบบ Android ถือว่าผู้ใช้สังเกตเห็นได้ สถานะนี้ครอบคลุมกระบวนการทั้งหมดที่ทำงานอยู่ ดังนี้
- บริการที่ทำงานอยู่เบื้องหน้า (FGS)
- งานด่วน
- งานการโอนข้อมูลที่เริ่มต้นโดยผู้ใช้
- บริการที่ผูกกับระบบหรือบริการที่แอปพลิเคชันอื่นๆ ผูกไว้
เนื่องจากบริการที่รับรู้ได้ออกแบบมาสำหรับงานเบื้องหลังที่สำคัญและใช้เวลานาน จึงมีแนวโน้มที่จะเกิดการรั่วไหลของวงจรชีวิตสะสมได้ง่าย ขีดจำกัดหน่วยความจำของแพลตฟอร์ม Android จะถือว่าสถานะนี้ไม่ใช่เบื้องหน้า ซึ่งหมายความว่าหากเกมของคุณทำงานอยู่เบื้องหลังแต่ยังคงเรียกใช้บริการที่รับรู้ได้ เกมจะอยู่ภายใต้ขีดจำกัดหน่วยความจำเบื้องหลังหรือบริการที่เข้มงวดมากขึ้นซึ่งแสดงอยู่ในหน้าศูนย์ช่วยเหลือของ Play เกมต้องตัดองค์ประกอบที่ไม่จำเป็นออกอย่างรุนแรงเมื่อย้ายจากเบื้องหน้าไปยังสถานะบริการที่รับรู้ได้เบื้องหลัง
ข้อกำหนดของ R8
Google Play Console จะประเมินการเพิ่มประสิทธิภาพโค้ดเป็นส่วนหนึ่งของหลักเกณฑ์ด้านคุณภาพของแอป เพื่อลดขนาดไบต์โค้ดและลดค่าใช้จ่ายพื้นฐานของกระบวนการ Java ดูรายละเอียดเพิ่มเติมเกี่ยวกับการกำหนดค่าไปป์ไลน์การสร้างได้ที่คู่มือเปิดใช้การเพิ่มประสิทธิภาพแอปด้วย R8
หากต้องการกำหนดค่า R8 ในโปรเจ็กต์ ให้ทำตามคู่มือเปิดใช้การเพิ่มประสิทธิภาพแอปด้วย R8 หากต้องการเปิดใช้การตั้งค่าการลดขนาดและการเพิ่มประสิทธิภาพขั้นสูง ให้ดูที่หัวข้อ ใช้ R8 ใน โหมดเต็ม หากต้องการระบุว่ากฎใดที่ป้องกันไม่ให้ R8 ทำให้คลาสสับสน หรือนำโค้ดที่ไม่ได้ใช้แล้วออก ให้ใช้เครื่องมือวิเคราะห์การกำหนดค่า R8
ข้อกำหนดของบิตแมป
บิตแมปเป็นส่วนสำคัญของการใช้หน่วยความจำในเกมที่มีรายละเอียดเสมือนจริงสูงในปัจจุบัน เนื่องจากระบบจะจัดเก็บข้อมูลพิกเซลของบิตแมปไว้ในฮีปแบบเนทีฟที่ไม่ได้จัดการโดยตรงใน Android 8.0 (API ระดับ 26) ขึ้นไป การโหลดรูปภาพที่ไม่ได้เพิ่มประสิทธิภาพอาจทำให้กระบวนการใช้หน่วยความจำเกินเกณฑ์ของแพลตฟอร์ม ดูแนวทางปฏิบัติแนะนำเกี่ยวกับการปรับขนาดและการแคชรูปภาพได้ที่หัวข้อเพิ่มประสิทธิภาพการใช้รูปภาพ
ตรวจสอบการใช้งานหน่วยความจำ
คุณต้องเข้าใจวิธีที่แพลตฟอร์ม Android วัดการใช้หน่วยความจำก่อนจึงจะเพิ่มประสิทธิภาพหน่วยความจำของเกมได้อย่างมีประสิทธิภาพ Android 17 อัปเดตเมตริกหน่วยความจำเพื่อติดตามผลรวมของ RSS แบบไม่ระบุตัวตน (RssAnon) และ Swap ที่ไม่ได้บีบอัด (VmSwap) โดยไม่รวมหน่วยความจำที่สำรองข้อมูลไว้ในไฟล์หรือหน่วยความจำส่วนตัวของ GPU คู่มือนี้จะอธิบายรายละเอียดเกี่ยวกับวิธีใช้ประโยชน์จากเครื่องมือระดับระบบ เช่น Perfetto และ meminfo ใช้ API การวินิจฉัย เช่น ProfilingManager และ onTrimMemory รวมถึงแยกการจัดสรรหน่วยความจำที่แม่นยำภายใน Unity และ Unreal Engine ทำความเข้าใจวิธีสร้างโปรไฟล์เกมอย่างแม่นยำและหลีกเลี่ยงการกระตุกของประสิทธิภาพที่เกี่ยวข้องกับการโพลหน่วยความจำรันไทม์แบบดั้งเดิม
ดูข้อมูลเพิ่มเติมได้ที่หัวข้อตรวจสอบการใช้งานหน่วยความจำ
กลยุทธ์การลดหน่วยความจำ
แม้ว่าเอนจินเกมจะช่วยลดความซับซ้อนของการพัฒนาข้ามแพลตฟอร์ม แต่การจัดการหน่วยความจำเริ่มต้นของเอนจินอาจทำให้เกิดขีดจำกัดหน่วยความจำระดับระบบปฏิบัติการ หน้านี้จะอธิบายขั้นตอนการเพิ่มประสิทธิภาพที่ใช้งานได้จริงซึ่งปรับแต่งมาสำหรับ Unity และ Unreal Engine โดยเฉพาะ ทำความเข้าใจว่าทำไมการใช้ onTrimMemory ที่อิงตาม Java อาจทำให้เกิดการล็อกตายใน Unity และวิธีใช้การเรียกกลับวงจรชีวิตแบบเนทีฟแทน นอกจากนี้ คุณจะได้พบกับการเพิ่มประสิทธิภาพระดับองค์ประกอบที่สำคัญ เช่น การใช้การบีบอัดพื้นผิว ASTC 8x8 และการกำหนดค่าการยกเลิกการโหลดองค์ประกอบ เพื่อให้เกมทำงานได้อย่างราบรื่นในทุกระดับฮาร์ดแวร์
ดูข้อมูลเพิ่มเติมได้ที่หัวข้อลดการใช้งานหน่วยความจำ