หากต้องการเพิ่มประสิทธิภาพการใช้หน่วยความจำที่ใช้ของเกมอย่างมีประสิทธิภาพ คุณต้องทำความเข้าใจก่อนว่าแพลตฟอร์ม Android วัดหน่วยความจำอย่างไร รวมถึงวิธีใช้การวัดและส่งข้อมูลทางไกลของระบบ, Diagnostic API และเครื่องมือสร้างโปรไฟล์ คู่มือนี้จะอธิบายรายละเอียดเกี่ยวกับวิธีตรวจสอบ บันทึก และวิเคราะห์การจัดสรรหน่วยความจำของเกมตามหลักเกณฑ์ใหม่ของแพลตฟอร์ม
ทำความเข้าใจเมตริก RSS และ Swap
หากต้องการวิเคราะห์และแก้ไขข้อบกพร่องเกี่ยวกับลักษณะการทำงานของหน่วยความจำในเกมอย่างมีประสิทธิภาพ คุณต้องทำความเข้าใจเมตริกทางเทคนิคที่แพลตฟอร์ม Android ใช้สำหรับการจัดการหน่วยความจำ ดูข้อมูลพื้นฐานโดยละเอียดเกี่ยวกับวิธีประมวลผลและตรวจสอบพารามิเตอร์การวัดและส่งข้อมูลทางไกลนี้ ในสภาพแวดล้อมจริงได้ที่ เอกสารประกอบ Android Vitals - การใช้งานหน่วยความจำ (RSS แบบไม่ระบุตัวตน + Swap)
1. RSS แบบไม่ระบุตัวตน (RssAnon)
ขนาดชุดหน่วยความจำที่ใช้งานอยู่ (Resident Set Size หรือ RSS) จะวัดส่วนของหน่วยความจำที่กระบวนการใช้และเก็บไว้ใน RAM จริงของอุปกรณ์ RSS แบ่งออกเป็นหน่วยความจำที่สำรองด้วยไฟล์และหน่วยความจำแบบไม่ระบุตัวตน เมตริกหน่วยความจำของ Android มุ่งเน้นไปที่ RSS แบบไม่ระบุตัวตนเท่านั้น โดยมีรายละเอียดดังนี้
- สิ่งที่รวมอยู่: หน้าหน่วยความจำที่กระบวนการของเกมจัดสรรโดยตรง ซึ่งไม่ได้ลิงก์กับไฟล์จริงในพื้นที่เก็บข้อมูล หน้าเหล่านี้รวมถึงฮีปของ Java หรือ Kotlin, สแต็กการดำเนินการของเธรด และที่สำคัญคือการจัดสรรหน่วยความจำเนทีฟ (เช่น ตัวจัดสรรเครื่องมือ C++ ที่กำหนดเอง หรือบล็อกหน่วยความจำที่ขอโดยใช้ malloc หรือ new แบบเนทีฟ และมีการเปลี่ยนแปลงโดยตรรกะของเกม) ดูข้อมูลเพิ่มเติม เกี่ยวกับเมตริกนี้ได้ในพจนานุกรมหน่วยความจำของกระบวนการ (RSS)
- ความสำคัญ: เครื่องมือเกมใช้พูลหน่วยความจำเนทีฟขนาดใหญ่เพื่อจัดการ ฟิสิกส์ การแสดงผล และตรรกะ เนื่องจากพูลเหล่านี้ไม่ได้สำรองด้วยไฟล์ จึงอยู่ใน RSS แบบไม่ระบุตัวตนทั้งหมดและเป็นส่วนใหญ่ของหน่วยความจำจริงของเกม
2. Swap ที่ไม่ได้บีบอัด (VmSwap)
Android ไม่รองรับพื้นที่ Swap แบบดั้งเดิมที่ใช้ดิสก์เนื่องจากข้อจำกัดด้านการสึกหรอของพื้นที่เก็บข้อมูลแฟลชและความหน่วง แต่จะใช้ zRAM (Swap ที่ไม่ได้บีบอัด) แทน โดยมีรายละเอียดดังนี้
- สิ่งที่รวมอยู่: เมื่อการใช้ RAM จริงเพิ่มขึ้น Daemon การจัดการหน่วยความจำของเคอร์เนลจะบีบอัดหน้าแบบไม่ระบุตัวตนที่ไม่ได้ใช้งานและย้ายหน้าเหล่านั้นไปยังส่วนที่ไม่ได้บีบอัดของ RAM จริง (zRAM) ที่จัดไว้ให้
- การคำนวณเมตริก: ระบบจะติดตามข้อมูลนี้ตามขนาดที่ไม่ได้บีบอัด (VmSwap) เพื่อประเมินความต้องการหน่วยความจำจริงของเกม หากเกมจัดสรรหน่วยความจำและระบบ Swap หน่วยความจำนั้นไปยัง zRAM ระบบจะยังนับหน่วยความจำนั้นรวมอยู่ในหน่วยความจำทั้งหมดของเกม
3. สถานะของกระบวนการ
Android Vitals จะแบ่งการใช้งานหน่วยความจำตามสถานะของกระบวนการbroken down by process states in Android Vitals สำหรับนักพัฒนาเกม SDK หรือเกมของบุคคลที่สามอาจทริกเกอร์บริการที่ผู้ใช้รับรู้หรือบริการเบื้องหลังโดยไม่คาดคิด
- สิ่งที่รวมอยู่: เบื้องหน้า, บริการที่ผู้ใช้รับรู้, เบื้องหลัง และ แคช
- ความสำคัญ: สถานะของกระบวนการที่แตกต่างกันจะส่งผลต่อการจัดการหน่วยความจำของระบบปฏิบัติการ
Android ที่แตกต่างกัน คุณอาจไม่ทราบว่าเกมกำลังทำงานด้วยสถานะของกระบวนการที่ละเอียดอ่อนหาก SDK ของบุคคลที่สามทริกเกอร์งานเบื้องหลังโดยไม่ได้ตั้งใจ ตรวจสอบว่าเกมกำลังทำงานอยู่เบื้องหลังหรือไม่
โดยใช้
RunningAppProcessInfo
Application Programming Interface (API)
Android มี System API ที่ช่วยให้เกมตอบสนองต่อการใช้หน่วยความจำมากเกินไปแบบไดนามิกและบันทึกการวินิจฉัยหน่วยความจำโดยละเอียดในขณะรันไทม์
ตอบสนองต่อเหตุการณ์การลดหน่วยความจำ
ระบบใช้ 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.
}
}
}
}
ProfilingManager
ProfilingManager API เปิดตัวใน Android 15 (ระดับ API 35) ซึ่งช่วยให้แอปพลิเคชันบันทึกสแนปช็อตที่กำหนดไว้แบบเป็นโปรแกรม (เช่น โปรไฟล์ฮีป, การติดตามระบบ และฮีปดัมพ์ของ Java) ได้โดยตรงในขณะรันไทม์
นักพัฒนาแอปสามารถทริกเกอร์การบันทึกด้วยตนเองในฉากที่เฉพาะเจาะจง หรือลงทะเบียนทริกเกอร์อัตโนมัติ เช่น TRIGGER_TYPE_ANOMALY เพื่อทริกเกอร์การบันทึกโดยอัตโนมัติเมื่อกระบวนการของเกมละเมิดเกณฑ์ของตัวจำกัดหน่วยความจำ อย่างไรก็ตาม นักพัฒนาเกมต้องคำนึงถึงข้อจำกัดที่สำคัญในเครื่องมือเกมสมัยใหม่
หมายเหตุ: เครื่องมือเกมสมัยใหม่ (เช่น Unity หรือ Unreal) จะจัดการประสิทธิภาพการดำเนินการโดยการจัดสรรบล็อกหน่วยความจำเสมือนขนาดใหญ่ล่วงหน้าจากเคอร์เนลโดยใช้ mmap ที่มีแฟล็ก MAP_ANONYMOUS จากนั้นเครื่องมือจะใช้ตัวจัดสรรย่อยที่กำหนดเอง (เช่น ตัวจัดการหน่วยความจำเนทีฟของ Unity หรือ BinnedAllocators ของ Unreal) เพื่อแบ่งและจัดสรรบล็อกหน่วยความจำภายใน
ApplicationExitInfo
หากระบบหยุดเกมที่ทำงานอยู่เบื้องหลังหรือหยุดเกมเนื่องจากละเมิดขีดจำกัดหน่วยความจำของกระบวนการแต่ละรายการ กลไกการดัมพ์ข้อมูลเมื่อเกิดข้อขัดข้องแบบเนทีฟหรือ Java มาตรฐาน (เช่น Firebase Crashlytics) จะไม่ลงทะเบียนเหตุการณ์ นักพัฒนาแอปควรใช้ประโยชน์จาก
ApplicationExitInfo API เมื่อเริ่มต้นเกมเพื่อค้นหาและบันทึกการหยุดทำงานเหล่านี้
แบบเป็นโปรแกรม
- การใช้งาน: เมื่อเริ่มต้น ให้เรียก
ActivityManager.getHistoricalProcessExitReasons()เพื่อดึงข้อมูลเหตุผลที่ทำให้เกิดการหยุดทำงานของเซสชันล่าสุด - เหตุผลหลักที่ทำให้เกิดการหยุดทำงานเนื่องจากหน่วยความจำ
REASON_LOW_MEMORY: บ่งชี้ว่าระบบหยุดกระบวนการเนื่องจากหน่วยความจำไม่เพียงพอ (Low Memory Killer หรือ LMK) การหยุดทำงานนี้เกิดขึ้นเมื่อการใช้หน่วยความจำทั่วทั้งอุปกรณ์สูงและระบบปฏิบัติการต้องเรียกคืน RAM เหตุผลที่ทำให้เกิดการหยุดทำงานนี้บ่งชี้ว่าหน่วยความจำเบื้องหลังของเกมมีขนาดใหญ่เกินไปจนไม่สามารถทำงานร่วมกับแอปพลิเคชันอื่นๆ ได้REASON_MEMORY_LIMITER(Android 17 (ระดับ API 37) ขึ้นไป): บ่งชี้ว่าระบบหยุดกระบวนการโดยเฉพาะเนื่องจากกระบวนการใช้หน่วยความจำเกินขีดจำกัดหน่วยความจำ cgroup (RssAnon + VmSwap) ที่ตัวจำกัดหน่วยความจำของแพลตฟอร์มกำหนด การหยุดทำงานนี้อาจเกิดขึ้นได้แม้ว่าอุปกรณ์จะมีหน่วยความจำจริงเหลืออยู่มาก ซึ่งแสดงว่ามีการละเมิดขีดจำกัดของกระบวนการแต่ละรายการโดยตรง
ใช้เครื่องมือที่พร้อมใช้งาน
ใช้เครื่องมือแพลตฟอร์มต่อไปนี้ระหว่างการพัฒนาและการประกันคุณภาพเพื่อวัดการใช้งานหน่วยความจำของเกมอย่างแม่นยำ
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 API (เบต้า) ได้ด้วย
ตรวจสอบ RssAnon และ Swap ใน Perfetto
หากต้องการตรวจสอบหน่วยความจำแบบไม่ระบุตัวตนและผลกระทบของ zRAM Swap ในเกม ให้โหลดไฟล์การติดตาม ใน UI ที่ใช้เว็บที่ ui.perfetto.dev แล้วทำตามเทคนิคการวิเคราะห์ เหล่านี้ ซึ่งออกแบบมาสำหรับการศึกษาเชิงลึกเกี่ยวกับหน่วยความจำ (ดูรายละเอียดเพิ่มเติมได้ที่ การศึกษาเชิงลึกเกี่ยวกับการวิเคราะห์หน่วยความจำด้วย Perfetto Case Studies)
1. การแสดงภาพตัวนับหน่วยความจำในไทม์ไลน์
- ค้นหากระบวนการ: ในรายการการนำทาง ให้ค้นหาชื่อแพ็กเกจหรือชื่อกระบวนการของเกม
- ขยายกลุ่มแทร็ก: คลิกแถวกระบวนการเพื่อขยายแทร็กเธรด แล้วค้นหากลุ่มย่อยที่ชื่อว่าหน่วยความจำ
- วิเคราะห์แทร็ก:
- mem.rss.anon (RSS แบบไม่ระบุตัวตน): กราฟเส้นนี้แสดง RAM จริงแบบเรียลไทม์ ที่พูลหน่วยความจำที่ไม่ได้จัดการของเกมใช้ ตรวจสอบไทม์ไลน์นี้ระหว่างการโหลดฉาก ป๊อปอัป UI หรือการเปลี่ยนผ่านของเกมเพลย์เพื่อตรวจสอบการใช้งานหน่วยความจำสูงสุด
- mem.swap (Swap ที่บีบอัดหรือ VmSwap): กราฟนี้จะพล็อต ขนาดของบล็อกหน่วยความจำก่อนบีบอัดที่ย้ายไปยัง zRAM กิจกรรม Swap สูงที่เกิดขึ้นพร้อมกับการเล่นเกมบ่งชี้ว่าเกมกำลังทำงานในอุปกรณ์ที่มีหน่วยความจำจำกัดและระบบกำลังบีบอัดชิ้นงานเบื้องหลังอย่างต่อเนื่อง
2. การเรียกใช้การค้นหา SQL (ตัวประมวลผลการติดตาม) หากต้องการวิเคราะห์แบบออฟไลน์โดยละเอียด คุณ สามารถเรียกใช้การค้นหา SQL ได้โดยตรงภายในคอนโซล UI ของ Perfetto หรือใช้ ไลบรารี Python แบบสแตนด์อโลนของตัวประมวลผลการติดตามเพื่อคำนวณ การใช้งานหน่วยความจำสูงสุดทางสถิติ
ค้นหาการจัดสรร RSS แบบไม่ระบุตัวตนสูงสุด
SELECT max(value) / 1024 / 1024 AS max_rss_anon_mb FROM counter JOIN counter_track ON counter.track_id = counter_track.id WHERE counter_track.name = 'mem.rss.anon' AND counter_track.upid IN ( SELECT upid FROM process WHERE name = 'your.game.package.name' );เชื่อมโยง RssAnon และ VmSwap ที่การประทับเวลาที่กำหนด
SELECT ts, track.name AS metric_type, value / 1024 / 1024 AS size_mb FROM counter JOIN counter_track track ON counter.track_id = track.id WHERE (track.name = 'mem.rss.anon' OR track.name = 'mem.swap') AND track.upid IN ( SELECT upid FROM process WHERE name = 'your.game.package.name' ) ORDER BY ts ASC;
ดูรายละเอียดเพิ่มเติมเกี่ยวกับการตรวจสอบไฟล์การติดตามโดยใช้ Android Studio ได้ที่หัวข้อตรวจสอบ การติดตามระบบ: หน่วยความจำของกระบวนการ (RSS) ดูรายละเอียดเกี่ยวกับการเขียนสคริปต์โปรไฟล์หน่วยความจำ ได้ที่หัวข้อบันทึกการจัดสรรแบบเนทีฟ
heapprofd
heapprofd เป็นเครื่องมือติดตามหน่วยความจำซึ่งเป็นส่วนหนึ่งของ Perfetto เครื่องมือนี้ช่วยคุณค้นหาหน่วยความจำรั่วได้โดยแสดงตำแหน่งที่จัดสรรหน่วยความจำโดยใช้ malloc คุณสามารถเริ่ม heapprofd ได้โดยใช้สคริปต์ Python และเนื่องจากเครื่องมือนี้มีค่าใช้จ่ายต่ำ จึงไม่ส่งผลต่อประสิทธิภาพการทำงานเหมือนเครื่องมืออื่นๆ เช่น Malloc Debug
bugreport
bugreport เป็นเครื่องมือบันทึกเพื่อดูว่าเกมขัดข้องเนื่องจากหน่วยความจำเต็มหรือไม่ เอาต์พุตของเครื่องมือนี้มีรายละเอียดมากกว่าการใช้ logcat มาก เครื่องมือนี้มีประโยชน์สำหรับการแก้ไขข้อบกพร่องเกี่ยวกับหน่วยความจำ เนื่องจากจะแสดงว่าเกมขัดข้องเนื่องจากหน่วยความจำเต็มหรือระบบหยุดเกมเนื่องจากหน่วยความจำไม่เพียงพอ (LMK)
ดูข้อมูลเพิ่มเติมได้ที่หัวข้อ บันทึกและอ่านรายงานข้อบกพร่อง
เครื่องมือเกมเอนจิน
แม้ว่าบันทึกระดับแพลตฟอร์มและการวัดและส่งข้อมูลทางไกลของระบบจะมีความสำคัญต่อการติดตามเกณฑ์และการปฏิบัติตามข้อกำหนดของระบบปฏิบัติการ แต่เครื่องมือเฉพาะของเครื่องมือเกมจะช่วยคุณระบุแหล่งที่มาของการจัดสรรไปยังออบเจ็กต์ของเกม ลักษณะการทำงานของสคริปต์ และลำดับชั้นของฉากที่ใช้งานอยู่ได้โดยตรง
Unity
ในสภาพแวดล้อม Unity Engine คุณสามารถประมาณการหน่วยความจำที่ใช้ RSS แบบไม่ระบุตัวตน + Swap ของ Android ได้อย่างแม่นยำในขณะรันไทม์ด้วยความน่าเชื่อถือสูง (โดยทั่วไปจะแสดงความแปรปรวนน้อยกว่า 10% เมื่อเทียบกับค่าระดับระบบปฏิบัติการจริง) โดยใช้เครื่องมือและคลาสการสร้างโปรไฟล์แบบเนทีฟของ Unity
ดูบทแนะนำแบบทีละขั้นตอนฉบับสมบูรณ์ ซึ่งรวมถึงกฎการกำหนดค่าและสคริปต์รันไทม์ ได้ที่หัวข้อวิธีตรวจสอบหน่วยความจำด้วยเครื่องมือ Unity
- Unity Profiler API: คุณสามารถประมาณการ
หน่วยความจำที่ไม่ได้จัดการของเกมแบบเป็นโปรแกรมในขณะรันไทม์ได้โดยการค้นหาเมตริกหลักของเครื่องมือ ดังนี้
- การใช้คลาส Profiler: ติดตามการจัดสรรหน่วยความจำทั้งหมดโดยการรวม
ค่า
Profiler.GetTotalReservedMemoryLong()และProfiler.GetMonoHeapSizeLong() - การใช้คลาส
ProfilerRecorder: ตรวจสอบหมวดหมู่หน่วยความจำ แบบไดนามิก หากต้องการสร้างค่าประมาณพื้นฐานที่เชื่อถือได้ ให้ดึงข้อมูลหน่วยความจำที่สงวนไว้ทั้งหมด (ในบิลด์เวอร์ชันที่เผยแพร่) หรือลบหน่วยความจำที่สงวนไว้ของ Gfx ออกจากหน่วยความจำที่สงวนไว้ทั้งหมด (ในบิลด์เวอร์ชันที่พัฒนา) เพื่อนำคอมโพเนนต์หน่วยความจำกราฟิกที่สำรองด้วยไฟล์ออก
- การใช้คลาส Profiler: ติดตามการจัดสรรหน่วยความจำทั้งหมดโดยการรวม
ค่า
- Unity Memory Profiler: หากต้องการระบุและแก้ไขข้อบกพร่องเกี่ยวกับหน่วยความจำรั่วแบบออฟไลน์
ให้บันทึกสแนปช็อตหน่วยความจำและตรวจสอบแผนภูมิหน่วยความจำที่ใช้งานอยู่บนอุปกรณ์
ในส่วนหน่วยความจำทั้งหมด หากต้องการคำนวณหน่วยความจำโดยประมาณ ให้รวมผลรวมของหมวดหมู่ต่อไปนี้ ไม่ได้ติดตาม, Android Runtime, เนทีฟ และมีการจัดการ
- ข้อจำกัดของ zRAM: ในสภาวะที่หน่วยความจำจำกัด เคอร์เนลของ Android จะบีบอัดหน้าหน่วยความจำที่ไม่ได้ใช้งานลงในพื้นที่ Swap (zRAM) เนื่องจาก Unity Memory Profiler ตรวจหาพารามิเตอร์ Swap ระดับระบบปฏิบัติการไม่ได้ คุณจึงอาจเห็นความคลาดเคลื่อนเล็กน้อยของหน่วยความจำระหว่างฉากที่มีการใช้หน่วยความจำมาก ตรวจสอบเพื่อเปรียบเทียบค่าประมาณกับ Perfetto เพื่อยืนยันค่าที่แน่นอน
Unreal
ในสภาพแวดล้อม Unreal Engine คุณสามารถประเมินหน่วยความจำที่ใช้ของเกมได้โดยการรวมการวินิจฉัยเครื่องมือกับการวัดและส่งข้อมูลทางไกลของแพลตฟอร์ม ดูวิธีการแบบทีละขั้นตอน และเวิร์กโฟลว์การสร้างโปรไฟล์ได้ที่หัวข้อตรวจสอบการใช้งานหน่วยความจำด้วย Unreal Engine
เครื่องมือและอินเทอร์เฟซการวินิจฉัยหลัก ได้แก่
- C++ Diagnostics API: ใช้
GetMemoryUsedFastสำหรับหน่วยความจำแบบเบา การค้นหา และใช้อินเทอร์เฟซGetStatsสำหรับสถิติหน่วยความจำระดับฮาร์ดแวร์ - คำสั่งคอนโซล: ตรวจสอบแนวโน้มการจัดสรรหน่วยความจำแบบเรียลไทม์ในฮาร์ดแวร์ของอุปกรณ์โดยใช้คำสั่งเครื่องมือ
stat unitและstat unitmax - Unreal Insights: ตรวจสอบการบันทึกไทม์ไลน์ที่แม่นยำระดับเฟรมเพื่อวิเคราะห์ เมตริกระดับแพลตฟอร์มและตัวนับหน่วยความจำที่กำหนดเอง