จัดการความจำอย่างมีประสิทธิภาพในเกม

ในแพลตฟอร์ม 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 เสียชีวิต

สำหรับข้อมูลเพิ่มเติม โปรดดู บันทึกและอ่านรายงานข้อบกพร่อง