ในแพลตฟอร์ม Android ระบบจะพยายามใช้หน่วยความจำระบบ (RAM) ให้ได้มากที่สุด และเพิ่มประสิทธิภาพหน่วยความจําต่างๆ เพื่อเพิ่มพื้นที่ว่างเมื่อจำเป็น การเพิ่มประสิทธิภาพเหล่านี้อาจส่งผลเสียต่อเกมของคุณ ไม่ว่าจะเป็นการทำให้เกมช้าลง ล่มไปเลย หรือลบไปเลย ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพเหล่านี้ได้ในหัวข้อการจัดสรรหน่วยความจำระหว่างกระบวนการ
หน้านี้จะอธิบายขั้นตอนที่คุณสามารถดำเนินการเพื่อหลีกเลี่ยงสภาวะหน่วยความจำต่ำ ที่ส่งผลต่อเกมของคุณ
ตอบสนองต่อ onTrimMemory()
ระบบจะใช้
onTrimMemory()
เพื่อแจ้งเตือนแอปของคุณเกี่ยวกับเหตุการณ์ในวงจรซึ่งแสดงโอกาสที่ดีสําหรับ
เพื่อลดการใช้หน่วยความจำโดยสมัครใจและหลีกเลี่ยงไม่ให้ถูกสิ้นสุดการใช้งาน
ฆาตกรรมที่มีหน่วยความจำต่ำ (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. } } } }
C#
using UnityEngine; using System.Collections; using System.Collections.Generic; class LowMemoryTrigger : MonoBehaviour { private void Start() { Application.lowMemory += OnLowMemory; } private void OnLowMemory() { // Respond to low memory condition (e.g., Resources.UnloadUnusedAssets()) } }
ใช้ Memory Advice API รุ่นเบต้า
Memory Advice API พัฒนาขึ้นเป็น
อีกทางเลือกหนึ่งแทน onTrimMemory ที่มีความอ่อนไหวและความแม่นยำสูงกว่ามาก
คาดการณ์ LMK ที่จะเกิดขึ้น API นี้บรรลุเป้าหมายนี้โดยการประมาณปริมาณ
ทรัพยากรหน่วยความจำที่ใช้งานอยู่แล้ว จากนั้นจะแจ้งเตือนแอปพลิเคชันเมื่อ
เกินเกณฑ์ นอกจากนี้ API ยังรายงานเปอร์เซ็นต์โดยประมาณของการใช้หน่วยความจำไปยังแอปของคุณโดยตรงได้ด้วย คุณสามารถใช้ Memory Advice API เป็นทางเลือกแทนเหตุการณ์ onTrimMemory
เพื่อวัตถุประสงค์ในการจัดการหน่วยความจำ
ในการใช้ Memory Advice API ให้ใช้ เริ่มต้นใช้งาน
ประหยัดหน่วยความจำโดยใช้งบประมาณหน่วยความจำ
กำหนดงบประมาณหน่วยความจำอย่างระมัดระวังเพื่อไม่ให้หน่วยความจำหมด บางรายการที่ โปรดพิจารณาสิ่งต่อไปนี้
- ขนาดของ RAM จริง: เกมมักจะใช้พื้นที่ระหว่าง 1⁄4 ถึง 1⁄2 ของตัวเกม จำนวน RAM ในอุปกรณ์
- ขนาด zRAM สูงสุด: zRAM ที่มากขึ้นหมายความว่าเกมอาจมีหน่วยความจำมากขึ้น
จัดสรรได้ จำนวนเงินนี้อาจแตกต่างกันไปตามอุปกรณ์ ให้มองหา
SwapTotal
ใน/proc/meminfo
เพื่อค้นหาค่านี้ - การใช้งานหน่วยความจำของระบบปฏิบัติการ: อุปกรณ์ที่กำหนด RAM ให้กับระบบมากขึ้น กระบวนการต่างๆ จะเพิ่มหน่วยความจำสำหรับเกมของคุณน้อยลง ระบบจะทำให้เกมของคุณไม่ทำงาน ก่อนที่จะหยุดการทำงานของระบบ
- การใช้หน่วยความจำของแอปที่ติดตั้ง: ทดสอบเกมในอุปกรณ์ที่ติดตั้งแอปไว้หลายรายการ แอปโซเชียลมีเดียและแชทต้องทำงานอย่างต่อเนื่องและส่งผลต่อ ปริมาณหน่วยความจำที่ว่างอยู่
หากไม่สามารถกำหนดงบประมาณหน่วยความจำแบบอนุรักษ์นิยมได้ ให้ใช้แนวทางที่ยืดหยุ่นมากขึ้น หากระบบประสบปัญหาหน่วยความจำต่ำ ให้ลดจำนวนหน่วยความจำ
ที่เกมใช้อยู่ เช่น จัดสรรพื้นผิวที่มีความละเอียดต่ำลงหรือจัดเก็บเชดเดอร์น้อยลงเพื่อตอบสนองต่อ onTrimMemory()
การใช้หน่วยความจำแบบไดนามิก
นักพัฒนาซอฟต์แวร์ต้องปรับปรุงการจัดสรรให้ดียิ่งขึ้น โดยเฉพาะอย่างยิ่งในการออกแบบเกม
หลีกเลี่ยงการข้าม
การกระตุกเกิดขึ้นเมื่อหน่วยความจำว่างเหลือน้อย แต่ไม่ต่ำพอที่จะทำให้เกมตายได้
ในกรณีนี้ kswapd
ได้อ้างสิทธิ์หน้าเว็บที่เกมยังต้องการอยู่ ดังนั้น
พยายามโหลดหน้าซ้ำจากหน่วยความจำ มีพื้นที่ว่างไม่เพียงพอ หน้าต่างๆ
ถูกสลับเปลี่ยนไปเรื่อยๆ (สลับกันอย่างต่อเนื่อง)
การติดตามระบบรายงานสถานการณ์นี้เป็นชุดข้อความ
โดย kswapd
จะทำงานอย่างต่อเนื่อง
อาการหนึ่งของการ Thrash คือเวลาที่อยู่ในเฟรมนาน อาจใช้เวลาสัก 1 วินาทีหรือมากกว่านั้น ลด (Reduce) หน่วยความจำของเกมเพื่อแก้ไขสถานการณ์นี้
ใช้เครื่องมือที่มีอยู่
Android มีคอลเล็กชันเครื่องมือเพื่อช่วยให้เข้าใจวิธีที่ระบบ จัดการหน่วยความจำ
Meminfo
เครื่องมือนี้จะเก็บรวบรวมสถิติหน่วยความจำเพื่อแสดงปริมาณ หน่วยความจำ PSS และหมวดหมู่ที่ใช้
พิมพ์สถิติ meminfo ใน ด้วยวิธีต่อไปนี้
- ใช้คำสั่ง
adb shell dumpsys meminfo package-name
- ใช้การโทร
MemoryInfo
จาก Android Debug API
สถิติ PrivateDirty
แสดงพารามิเตอร์
จำนวน RAM ในกระบวนการนี้ที่ไม่สามารถแบ่งหน้าลงในดิสก์ได้และไม่ได้แชร์
กับกระบวนการอื่นๆ เงินจำนวนนี้สามารถนำไปใช้ได้กับ
เมื่อระบบยกเลิกกระบวนการนั้น
จุดติดตามหน่วยความจำ
จุดติดตามหน่วยความจำจะติดตามปริมาณ หน่วยความจำ RSS เกมที่คุณกำลังใช้อยู่ การคำนวณการใช้หน่วยความจำ RSS นั้นเร็วกว่าการคำนวณมาก การใช้งาน PSS เนื่องจากการคำนวณได้เร็วกว่า RSS จะแสดงรายละเอียดที่ละเอียดยิ่งขึ้นบน เปลี่ยนขนาดหน่วยความจำเพื่อให้วัดการใช้งานหน่วยความจำสูงสุดได้แม่นยำมากขึ้น จึงเป็นเรื่องง่ายที่จะสังเกตเห็นจุดสูงสุดที่อาจทำให้เกมหมด ความทรงจำ
Perfetto และการติดตามยาว
Perfetto คือชุดเครื่องมือสำหรับรวบรวมข้อมูลประสิทธิภาพและหน่วยความจำในอุปกรณ์ และแสดงใน UI บนเว็บ ซึ่งรองรับการติดตามที่ยาวเท่าใดก็ได้เพื่อให้คุณดูการเปลี่ยนแปลงของ RSS เมื่อเวลาผ่านไปได้ นอกจากนี้ ยังออกการค้นหา SQL จากข้อมูลที่สร้างขึ้นเพื่อประมวลผลแบบออฟไลน์ได้ด้วย เปิดใช้งานการติดตามแบบยาวจาก แอป System Tracing ตรวจสอบว่า หมวดหมู่ memory:Memory เปิดใช้อยู่สำหรับการติดตาม
heapprofd
heapprofd
เป็นเครื่องมือติดตามหน่วยความจำ
ซึ่งเป็นส่วนหนึ่งของ Perfetto เครื่องมือนี้จะช่วยให้คุณค้นพบการรั่วไหลจากหน่วยความจำได้โดยการแสดง
ที่มีการจัดสรรหน่วยความจำโดยใช้ malloc
heapprofd
สามารถเริ่มใช้
สคริปต์ Python และเนื่องจากเครื่องมือโอเวอร์เฮดต่ำ จึงไม่ส่งผลกระทบต่อ
เช่นเดียวกับเครื่องมืออื่นๆ เช่น Malloc Debug
bugreport
bugreport
เป็นเครื่องมือบันทึกสำหรับใช้ค้นหาว่าเกมขัดข้องหรือไม่
เพราะหน่วยความจำเต็ม เอาต์พุตของเครื่องมือนี้จะละเอียดกว่าการใช้ logcat มาก มีประโยชน์ในการแก้ไขข้อบกพร่องของหน่วยความจำเพราะจะแสดงว่าเกมของคุณขัดข้องหรือไม่
เพราะหน่วยความจำเต็ม
หรือถูก LMK เสียชีวิต
สำหรับข้อมูลเพิ่มเติม โปรดดู บันทึกและอ่านรายงานข้อบกพร่อง