ในแพลตฟอร์ม Android ระบบจะพยายามใช้หน่วยความจำของระบบ (RAM) ให้มากที่สุด เท่าที่จะทำได้ และทำการเพิ่มประสิทธิภาพหน่วยความจำต่างๆ เพื่อเพิ่มพื้นที่ว่างเมื่อจำเป็น การเพิ่มประสิทธิภาพเหล่านี้อาจส่งผลเสียต่อเกม ไม่ว่าจะทำให้เกมช้าลงหรือหยุดทำงานไปเลย ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพเหล่านี้ได้ ในหัวข้อ การจัดสรรหน่วยความจำระหว่างกระบวนการ
หน้านี้จะอธิบายขั้นตอนที่คุณสามารถทำเพื่อหลีกเลี่ยงสภาวะหน่วยความจำเหลือน้อย ที่ส่งผลต่อเกม
ตอบสนองต่อ onTrimMemory()
ระบบใช้
onTrimMemory()
เพื่อแจ้งให้แอปทราบถึงเหตุการณ์ในวงจรของแอปซึ่งเป็นโอกาสที่ดีสำหรับ
แอปในการลดการใช้งานหน่วยความจำโดยสมัครใจและหลีกเลี่ยงไม่ให้Low-Memory Killer (LMK)
หยุดการทำงานเพื่อปล่อยหน่วยความจำให้แอปอื่นๆ ใช้
หากระบบปิดแอปของคุณในเบื้องหลัง ครั้งถัดไปที่ผู้ใช้เปิดแอป ของคุณ ผู้ใช้จะพบกับCold Start ที่ช้า แอปที่ลดการใช้งานหน่วยความจำเมื่อเข้าสู่เบื้องหลังมีแนวโน้มที่จะถูกปิดในเบื้องหลังน้อยกว่า
เมื่อตอบสนองต่อเหตุการณ์การตัดแต่ง สิ่งที่ดีที่สุดคือการปล่อยการจัดสรรหน่วยความจำขนาดใหญ่
ซึ่งไม่จำเป็นในทันทีและสามารถสร้างใหม่ได้ตามต้องการ ตัวอย่างเช่น หากแอปมีแคชของบิตแมปที่ถอดรหัสจากรูปภาพที่บีบอัดซึ่งจัดเก็บไว้ในเครื่อง การล้างหรือลบแคชนี้เพื่อตอบสนองต่อ TRIM_MEMORY_UI_HIDDEN มักจะเป็นความคิดที่ดี
Kotlin
class MainActivity : AppCompatActivity(), ComponentCallbacks2 { override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { public void onTrimMemory(int level) { switch (level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } } }
ใช้หน่วยความจำอย่างประหยัด
จัดสรรหน่วยความจำอย่างรอบคอบเพื่อไม่ให้หน่วยความจำหมด รายการบางอย่างที่ควรพิจารณามีดังนี้
- ขนาดของ RAM จริง: เกมมักจะใช้ RAM จริงในอุปกรณ์ประมาณ ¼ ถึง ½
- ขนาด zRAM สูงสุด: zRAM ที่มากขึ้นหมายความว่าเกมอาจมีหน่วยความจำมากขึ้น
ที่จะจัดสรร จำนวนนี้อาจแตกต่างกันไปตามอุปกรณ์ ให้มองหา
SwapTotalใน/proc/meminfoเพื่อดูค่านี้ - การใช้งานหน่วยความจำของระบบปฏิบัติการ: อุปกรณ์ที่กำหนด RAM ให้กับกระบวนการของระบบมากกว่า จะเหลือหน่วยความจำสำหรับเกมของคุณน้อยลง ระบบจะปิดกระบวนการของเกม ก่อนที่จะปิดกระบวนการของระบบ
- การใช้งานหน่วยความจำของแอปที่ติดตั้ง: ทดสอบเกมในอุปกรณ์ที่มีแอปจำนวนมากติดตั้งอยู่ แอปโซเชียลมีเดียและแอปแชทต้องทำงานอยู่ตลอดเวลาและส่งผลต่อ ปริมาณหน่วยความจำที่ว่าง
หากไม่สามารถใช้งบประมาณหน่วยความจำแบบประหยัดได้ ให้ใช้แนวทางที่ยืดหยุ่นกว่า
หากระบบพบปัญหาหน่วยความจำเหลือน้อย ให้ลดปริมาณหน่วยความจำ
ที่เกมใช้ เช่น จัดสรรพื้นผิวที่มีความละเอียดต่ำกว่าหรือจัดเก็บ
Shader น้อยลงเพื่อตอบสนองต่อ onTrimMemory() แนวทางแบบไดนามิกในการจัดสรรหน่วยความจำนี้
ต้องใช้ความพยายามจากนักพัฒนาซอฟต์แวร์มากขึ้น โดยเฉพาะอย่างยิ่งในระยะการออกแบบเกม
หลีกเลี่ยงการ Thrash
การ Thrashจะเกิดขึ้นเมื่อหน่วยความจำว่างเหลือน้อย แต่ไม่น้อยพอที่จะปิดเกม
ในกรณีนี้ kswapd ได้เรียกคืนหน้าเว็บที่เกมยังคงต้องการ ดังนั้นจึงพยายามโหลดหน้าเว็บจากหน่วยความจำอีกครั้ง มีพื้นที่ไม่เพียงพอ ระบบจึงสลับหน้า
ออกไปเรื่อยๆ (การสลับอย่างต่อเนื่อง)
การติดตามระบบจะรายงานสถานการณ์นี้เป็นเธรด
ที่ kswapd ทำงานอย่างต่อเนื่อง
อาการอย่างหนึ่งของการเกิด Thrashing คือเวลาเฟรมที่นาน ซึ่งอาจนานถึง 1 วินาทีหรือมากกว่า โปรดลดปริมาณหน่วยความจำที่ใช้ของเกมเพื่อแก้ไขปัญหานี้
ใช้เครื่องมือที่มี
Android มีชุดเครื่องมือที่จะช่วยให้คุณเข้าใจวิธีที่ระบบ จัดการหน่วยความจำ
Meminfo
เครื่องมือนี้จะรวบรวมสถิติหน่วยความจำเพื่อแสดงปริมาณ หน่วยความจำ PSS ที่จัดสรรและหมวดหมู่ที่ใช้
พิมพ์สถิติ meminfo โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
- ใช้คำสั่ง
adb shell dumpsys meminfo package-name - ใช้การเรียก
MemoryInfoจาก Android Debug API
สถิติ PrivateDirty แสดง
ปริมาณ RAM ภายในกระบวนการที่เพจไปยังดิสก์ไม่ได้และไม่ได้แชร์
กับกระบวนการอื่นๆ ระบบจะใช้เงินจำนวนมากนี้ได้เมื่อมีการสิ้นสุดกระบวนการดังกล่าว
จุดติดตามหน่วยความจำ
Tracepoint ของหน่วยความจำจะติดตามปริมาณหน่วยความจำ RSS ที่เกมของคุณใช้ การคำนวณการใช้งานหน่วยความจำ RSS เร็วกว่าการคำนวณการใช้งาน PSS มาก เนื่องจากคำนวณได้เร็วกว่า RSS จึงแสดงรายละเอียดที่ละเอียดยิ่งขึ้นเกี่ยวกับการเปลี่ยนแปลงขนาดหน่วยความจำเพื่อให้วัดการใช้งานหน่วยความจำสูงสุดได้แม่นยำยิ่งขึ้น ดังนั้น คุณจึงสังเกตเห็นจุดสูงสุดที่อาจทำให้เกมใช้หน่วยความจำจนหมดได้ง่ายขึ้น
Perfetto และการติดตามแบบยาว
Perfetto คือชุดเครื่องมือสำหรับรวบรวมข้อมูลประสิทธิภาพและหน่วยความจำในอุปกรณ์ แล้วแสดงใน UI บนเว็บ โดยรองรับการติดตามที่ยาวนานตามต้องการเพื่อให้คุณดูการเปลี่ยนแปลงของ RSS เมื่อเวลาผ่านไปได้ นอกจากนี้ คุณยังออกคำค้นหา SQL ในข้อมูลที่สร้างขึ้นเพื่อการประมวลผลแบบออฟไลน์ได้ด้วย เปิดใช้การติดตามแบบยาวจากแอปการติดตามระบบ ตรวจสอบว่าได้เปิดใช้หมวดหมู่memory:Memory สำหรับการติดตามแล้ว สําหรับการวัดหน่วยความจําที่กําหนดเองในการพัฒนาและการทดสอบ คุณยังใช้ (เบต้า) heapprofd API ได้ด้วย
heapprofd
heapprofd เป็นเครื่องมือติดตามหน่วยความจำ
ซึ่งเป็นส่วนหนึ่งของ Perfetto เครื่องมือนี้ช่วยคุณค้นหาหน่วยความจำรั่วได้โดยแสดงตำแหน่งที่จัดสรรหน่วยความจำโดยใช้ malloc heapprofd สามารถเริ่มต้นได้โดยใช้สคริปต์ Python และเนื่องจากเครื่องมือนี้มีค่าใช้จ่ายต่ำ จึงไม่ส่งผลต่อประสิทธิภาพเหมือนเครื่องมืออื่นๆ เช่น Malloc Debug
รายงานข้อบกพร่อง
bugreport เป็นเครื่องมือบันทึกข้อมูลเพื่อดูว่าเกมของคุณขัดข้องเนื่องจากหน่วยความจำไม่เพียงพอหรือไม่
เอาต์พุตของเครื่องมือมีรายละเอียดมากกว่าการใช้
logcat มาก ซึ่งมีประโยชน์สำหรับการแก้ไขข้อบกพร่องของหน่วยความจำ เนื่องจากจะแสดงว่าเกมของคุณขัดข้อง
เนื่องจากหน่วยความจำหมดหรือถูก LMK ปิด
ดูข้อมูลเพิ่มเติมได้ที่บันทึกและอ่านรายงานข้อบกพร่อง