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

ในแพลตฟอร์ม 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 จากข้อมูลที่สร้างขึ้นเพื่อประมวลผลแบบออฟไลน์ได้ด้วย เปิดใช้การติดตามแบบยาวจากแอปการติดตามระบบ ตรวจสอบว่าได้เปิดใช้หมวดหมู่ memory:Memory สำหรับการติดตามแล้ว

ฮีปโปรด

heapprofd เป็นเครื่องมือติดตามหน่วยความจำ ซึ่งเป็นส่วนหนึ่งของ Perfetto เครื่องมือนี้จะช่วยให้คุณค้นพบการรั่วไหลจากหน่วยความจำได้โดยการแสดง ที่มีการจัดสรรหน่วยความจำโดยใช้ malloc heapprofd สามารถเริ่มใช้ สคริปต์ Python และเนื่องจากเครื่องมือโอเวอร์เฮดต่ำ จึงไม่ส่งผลกระทบต่อ เช่นเดียวกับเครื่องมืออื่นๆ เช่น Malloc Debug

รายงานข้อบกพร่อง

bugreport เป็นเครื่องมือบันทึกสำหรับใช้ค้นหาว่าเกมขัดข้องหรือไม่ เพราะหน่วยความจำเต็ม เอาต์พุตของเครื่องมือมีรายละเอียดมากกว่าการใช้ Logcat มีประโยชน์ในการแก้ไขข้อบกพร่องของหน่วยความจำเพราะจะแสดงว่าเกมของคุณขัดข้องหรือไม่ เพราะหน่วยความจำเต็ม หรือถูก LMK เสียชีวิต

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