คู่มือเกมแลค › L10 หน่วยความจำ
หน่วยความจำรั่ว Memory leak
ID สาเหตุ mem-leak · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
หน่วยความจำที่ไม่ถูกคืนค่อย ๆ สะสม จนหลายวันต่อมานำไปสู่ GC ทำงานไม่หยุด, สวอป หรือโปรเซสถูกบังคับปิด
ทำไม ข้อมูลตัวละครที่ออกจากเกมไปแล้วและ event handler ไม่ถูกคืนหน่วยความจำ → ผลคือ หน่วยความจำว่างลดลงเรื่อย ๆ ตลอดหลายวัน → บนหน้าจอ หลังปิดปรับปรุงใหม่ ๆ ยังปกติ ยิ่งผ่านไปหลายวันยิ่งแลค สุดท้ายเซิร์ฟเวอร์ล่ม
- อาการ
- สโลว์โมชั่น, ค้าง, หลุด
- ปัจจัย
- การหยุดชะงัก
- ใครเจอ
- ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- ยิ่งเปิดไว้นานยิ่งเป็น, ช่วงพีคหัวค่ำ
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
- งานฝั่งทีมพัฒนาเกม
- วิเคราะห์ heap dump, ทดสอบโหลดต่อเนื่องเป็นเวลานาน
- งานฝั่งทีมอินฟรา
- มอนิเตอร์แนวโน้มการใช้หน่วยความจำของแต่ละโปรเซสและตั้ง alert
- บนกราฟ
- ค่อย ๆ สูงขึ้น · หน่วยความจำของโปรเซส (RSS), heap หลัง GC
- จุดที่ต้องดู
- ดูหน่วยความจำของโปรเซสเซิร์ฟเวอร์เกม (RSS จาก pidstat -r) เป็นช่วงหลายวัน และสำหรับเซิร์ฟเวอร์ที่ใช้ GC ให้ดู heap ที่เหลือหลัง GC Java ดูค่าหลัง GC จากปริมาณการใช้ก่อนและหลัง GC ในบรรทัดของ -Xlog:gc, .NET ดูขนาด heap หลัง GC ใน dotnet-counters (ตั้งแต่ .NET 9 คือ dotnet.gc.last_collection.heap.size, 8 ลงไปคือ GC Heap Size)
- สัญญาณว่าใช่
- heap ที่เหลือหลัง GC (เส้นฐาน) สูงขึ้นทุกวันหลังรีสตาร์ต และไม่ลดลงแม้ช่วงเช้ามืดที่ผู้เล่นน้อย
- สัญญาณว่าไม่ใช่
- เส้นฐานของ heap แบนราบแต่ RSS สูงขึ้นอย่างเดียว: น่าจะเป็น fragmentation (mem-fragment) หรือหน่วยความจำ native ถ้าขึ้นลงตามจำนวนผู้เล่นคือการใช้งานปกติ
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- ถ้ารีสตาร์ตทุกสัปดาห์ตอนปิดปรับปรุงตามรอบ อาการรั่วจะถูกกลบจนไม่มีใครเจอไปนาน และมักโผล่ขึ้นมากะทันหันเมื่อเลื่อนการปิดปรับปรุงไปหนึ่งครั้ง หรือเมื่อมีอีเวนต์ที่ทำให้ผู้เล่นเพิ่มขึ้น
แหล่งอ้างอิง
- Troubleshoot Memory Leaks Oracle
ถ้าโปรแกรมช้าลงเรื่อย ๆ ให้สงสัยหน่วยความจำรั่ว สุดท้ายหน่วยความจำจะหมดและโปรแกรมปิดตัวผิดปกติ, ข้อมูลหลักในการวิเคราะห์การรั่วคือ heap dump - Debug a memory leak in .NET .NET
แม้มี GC แต่ถ้ายังอ้างอิงออบเจ็กต์ที่ไม่ต้องใช้แล้วไว้ก็คือหน่วยความจำรั่ว ทำให้ประสิทธิภาพตกและเกิด OutOfMemoryException, ตรวจแนวโน้มหน่วยความจำและวิเคราะห์ dump - Garbage Collector Implementation Oracle
บรรทัดของ -Xlog:gc อยู่ในรูปแบบ “ปริมาณที่ใช้ก่อน GC->ปริมาณที่ใช้หลัง GC (ขนาด heap)” - dotnet-counters diagnostic tool .NET
ตั้งแต่ .NET 9 แสดงเป็น dotnet.gc.last_collection.heap.size ส่วน .NET 8 ลงไปแสดงเป็น GC Heap Size - pidstat(1) — Linux manual page sysstat
-r: RSS ของแต่ละโปรเซส (หน่วยความจำที่อยู่ใน RAM จริง) และ page fault
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L10 หน่วยความจำ
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (สโลว์โมชั่น)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง