คู่มือเกมแลค › L10 หน่วยความจำ
หน่วยความจำแตกกระจาย (fragmentation) Heap fragmentation
ID สาเหตุ mem-fragment · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าจัดสรรและคืนหน่วยความจำซ้ำไปมาจนพื้นที่ว่างแตกเป็นชิ้นเล็ก ๆ โปรเซสจะถือครองหน่วยความจำมากกว่าที่ใช้จริงมาก
ทำไม หลายเธรดจัดสรรและคืนหน่วยความจำขนาดไม่เท่ากันเป็นเวลานาน → ผลคือ พื้นที่ว่างกระจายเป็นชิ้นเล็ก ๆ คืนให้ OS ไม่ได้ ปริมาณการใช้จึงเพิ่มขึ้นเรื่อย ๆ เหมือนหน่วยความจำรั่ว → บนหน้าจอ ยิ่งเปิดไว้นานยิ่งช้าลงเพราะสวอปและหน่วยความจำไม่พอ แล้วถูกบังคับปิด
- อาการ
- สโลว์โมชั่น, หลุด
- ปัจจัย
- การหยุดชะงัก
- ใครเจอ
- ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- ยิ่งเปิดไว้นานยิ่งเป็น
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- ใช้ memory pool แยกตามขนาด, ใช้ allocator ที่ทนต่อ fragmentation (jemalloc, mimalloc ฯลฯ)
- บนกราฟ
- ค่อย ๆ สูงขึ้น · หน่วยความจำของโปรเซส (RSS)
- จุดที่ต้องดู
- รันเซิร์ฟเวอร์จากบิลด์เดียวกันสองตัว ตัวหนึ่งลดจำนวน arena ของ glibc ด้วยตัวแปรสภาพแวดล้อม MALLOC_ARENA_MAX หรือเปลี่ยนไปใช้ allocator อื่นอย่าง jemalloc แล้วเทียบ RSS จาก pidstat -r เป็นเวลาหลายวัน
- สัญญาณว่าใช่
- จำนวนผู้เล่นและจำนวนเอนทิตีใกล้เคียงกัน แต่เฉพาะเซิร์ฟเวอร์ที่เปลี่ยนแล้ว RSS หยุดเพิ่มหรือลดลงมาก
- สัญญาณว่าไม่ใช่
- เปลี่ยน allocator แล้วยังขึ้นเหมือนเดิม: หน่วยความจำที่ไม่ได้คืน (mem-leak)
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- รูปแบบเหมือนหน่วยความจำรั่ว การวิเคราะห์ heap จึงหาจุดที่รั่วไม่เจอ อาการนี้หนักเป็นพิเศษกับ allocator พื้นฐานของ Linux (glibc) บนเซิร์ฟเวอร์ที่มีเธรดเยอะ บางครั้งแค่เปลี่ยน allocator ปริมาณการใช้ก็ลดลงมาก
แหล่งอ้างอิง
- mallopt(3) — Linux manual page Linux man-pages
glibc malloc สร้าง arena ได้ถึงจำนวนที่เป็นพหุคูณของจำนวน CPU เพื่อลดการแย่งกันระหว่างเธรด และยิ่งมี arena มาก หน่วยความจำยิ่งถูกใช้มาก (จำกัดด้วย M_ARENA_MAX หรือตั้งผ่านตัวแปรสภาพแวดล้อม MALLOC_ARENA_MAX ก็ได้) - jemalloc memory allocator jemalloc
malloc อเนกประสงค์ที่เน้นหลีกเลี่ยง fragmentation และรองรับ concurrency ที่สเกลได้ดี - pidstat(1) — Linux manual page sysstat
-r: RSS ของแต่ละโปรเซส (หน่วยความจำที่อยู่ใน RAM จริง)
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L10 หน่วยความจำ
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (สโลว์โมชั่น)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง