เซิร์ฟเวอร์ Minecraft ที่กระตุก แลค และ TPS ตกไม่ได้เกิดจาก RAM น้อยเสมอไป หลายครั้งปัญหามาจากการตั้งค่า Java Virtual Machine (JVM) ที่ไม่เหมาะสม ทำให้เกิด Garbage Collection (GC) pause ยาวจนผู้เล่นรู้สึกสะดุด บทความนี้จะอธิบายวิธีจัดสรร RAM อย่างถูกต้อง ตั้งค่า -Xms และ -Xmx รวมถึงใช้ชุดพารามิเตอร์ยอดนิยมที่เรียกว่า Aikar's Flags เพื่อให้เซิร์ฟเวอร์ Paper/Spigot ของคุณลื่นไหลที่สุด
ทำไม RAM มากไม่ได้แปลว่าลื่นเสมอไป
ความเชื่อที่ว่า "ยิ่งให้ RAM เยอะยิ่งดี" เป็นความเข้าใจผิดที่พบบ่อยที่สุด การให้ heap ใหญ่เกินไปทำให้ GC ต้องกวาดหน่วยความจำก้อนใหญ่ในแต่ละรอบ ส่งผลให้เกิด pause ที่นานขึ้น ไม่ใช่สั้นลง นอกจากนี้ประสิทธิภาพของ Minecraft ส่วนใหญ่ถูกจำกัดด้วย CPU แบบ single-thread มากกว่าปริมาณ RAM เพราะ logic การ tick ของโลกเกมทำงานบนเธรดหลักเพียงเธรดเดียว
สรุปสั้น ๆ: RAM ที่เหมาะสมช่วยให้เกมมีที่หายใจ แต่ RAM ที่มากเกินไปกลับสร้าง GC pause ที่ยาวขึ้น และไม่ช่วยเพิ่ม TPS ถ้าคอขวดคือ CPU
เข้าใจ -Xms และ -Xmx อย่างถ่องแท้
พารามิเตอร์สองตัวนี้คือหัวใจของการจัดสรรหน่วยความจำ JVM:
-Xms= ขนาด heap เริ่มต้น (initial heap size) ที่ JVM จองทันทีตอนเริ่มทำงาน-Xmx= ขนาด heap สูงสุด (maximum heap size) ที่ JVM ขยายได้
ตั้งให้เท่ากันเสมอ
สำหรับเซิร์ฟเวอร์เกม ควรตั้ง -Xms ให้เท่ากับ -Xmx เสมอ เหตุผลคือถ้าตั้งไม่เท่ากัน JVM จะค่อย ๆ ขยาย heap เมื่อต้องการหน่วยความจำเพิ่ม การขยาย (heap resize) แต่ละครั้งทำให้เกิด pause ที่ผู้เล่นสัมผัสได้เป็นอาการกระตุก การตั้งให้เท่ากันตั้งแต่แรกทำให้ JVM จองพื้นที่ครบทันทีและไม่ต้องขยายอีก
อย่าให้ RAM ทั้งหมดของระบบกับ JVM
ข้อผิดพลาดร้ายแรงคือการตั้ง -Xmx เท่ากับ RAM ทั้งหมดของเครื่อง เพราะนอกจาก heap แล้ว Java ยังใช้หน่วยความจำ off-heap (Metaspace, thread stacks, native buffers) และตัวระบบปฏิบัติการเองก็ต้องการ RAM ด้วย ควรเผื่อไว้ให้ OS และส่วน off-heap ของ Minecraft ประมาณ 1-2GB เสมอ
คำเตือน: ถ้าตั้ง -Xmx สูงกว่า RAM ที่มีจริง ระบบ Linux จะเรียก OOM Killer มาฆ่าโปรเซส Java ทันที เซิร์ฟเวอร์จะดับกลางอากาศโดยไม่มีการเซฟ ให้เหลือ RAM สำหรับ OS อย่างน้อย 1-2GB เสมอ
Aikar's Flags: ชุดพารามิเตอร์มาตรฐาน
Aikar's Flags คือชุดพารามิเตอร์ JVM ที่พัฒนาโดย Aikar (นักพัฒนา PaperMC) ปรับจูน G1 Garbage Collector ให้เหมาะกับ workload ของ Minecraft โดยเฉพาะ เน้นลดความยาวของ GC pause แทนที่จะเน้น throughput ล้วน ๆ นี่คือชุดสำหรับ heap ขนาดไม่เกิน 12GB:
java -Xms4G -Xmx4G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -jar paper.jar --nogui
ความหมายของ flag สำคัญ:
-XX:+UseG1GCใช้ G1 Garbage Collector ที่ออกแบบมาเพื่อ pause สั้น-XX:MaxGCPauseMillis=200เป้าหมายให้ pause ไม่เกิน 200ms-XX:+AlwaysPreTouchแตะหน่วยความจำทั้งหมดตอนเริ่ม ทำให้ RAM ถูกจองจริงและลด page fault ตอนรัน-XX:+DisableExplicitGCป้องกันปลั๊กอินเรียก System.gc() ที่ทำให้เกิด full GC ไม่จำเป็น
ปรับ Flags เมื่อ RAM มากกว่า 12GB
ถ้าคุณจัดสรร heap มากกว่า 12GB (เช่นเซิร์ฟเวอร์ modded ขนาดใหญ่) Aikar แนะนำให้ปรับพารามิเตอร์บางตัวเพื่อให้ G1GC จัดการ heap ก้อนใหญ่ได้ดีขึ้น:
-XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=20 -XX:G1MixedGCCountTarget=8
เหตุผลคือ heap ที่ใหญ่ขึ้นต้องการ young generation ที่ใหญ่ขึ้น (G1NewSizePercent/G1MaxNewSizePercent สูงขึ้น) และ region ที่ใหญ่ขึ้น (G1HeapRegionSize=16M) เพื่อลดจำนวน region ที่ GC ต้องจัดการ ส่วน InitiatingHeapOccupancyPercent=20 ยอมให้ heap เต็มมากขึ้นก่อนเริ่ม concurrent cycle ซึ่งเหมาะกับ heap ใหญ่
TPS และ MSPT: ตัวชี้วัดที่แท้จริง
อย่าวัดความลื่นด้วยความรู้สึก ให้ดูตัวเลขจริง:
- TPS (Ticks Per Second) เป้าหมายคือ 20 tick/วินาที ถ้าต่ำกว่านี้แปลว่าเซิร์ฟเวอร์ตามงานไม่ทัน เกมจะช้าลง
- MSPT (Milliseconds Per Tick) เวลาที่ใช้ประมวลผลแต่ละ tick ควรต่ำกว่า 50ms (เพราะ 1000ms / 20 tick = 50ms) ถ้าเกิน 50ms TPS จะเริ่มตก
วินิจฉัยด้วย /spark หรือ /timings
ใช้ปลั๊กอิน /spark (แนะนำ) หรือคำสั่ง /timings เพื่อหา profiler ว่าอะไรกิน tick มากที่สุด เช่น entity เยอะเกินไป redstone ทำงานหนัก หรือปลั๊กอินตัวใดกินเวลา รายงานเหล่านี้บอกคุณได้ว่าปัญหาคือ RAM/GC หรือเป็น CPU-bound
เกร็ดสำคัญ: ถ้า TPS ตกแต่ RAM ยังเหลือเยอะและไม่มี GC pause ยาว ปัญหามักเป็น CPU-bound (single-thread) การเพิ่ม RAM จะไม่ช่วยเลย ต้องลดภาระบนเธรดหลักหรือย้ายไป CPU ที่แรงต่อคอร์กว่า
ตารางแนะนำ RAM ตามจำนวนผู้เล่น
ตัวเลขต่อไปนี้คือขนาด heap ที่ควรจัดสรรให้ JVM (ค่า Xmx) ไม่ใช่ RAM รวมของ VPS อย่าลืมเผื่อให้ OS อีก 1-2GB:
| จำนวนผู้เล่น | ประเภทเซิร์ฟเวอร์ | Heap ที่แนะนำ (Xmx) |
|---|---|---|
| 1-5 คน | Vanilla/Paper | 2-3GB |
| 5-15 คน | Paper + ปลั๊กอิน | 4GB |
| 15-30 คน | Paper + ปลั๊กอินเยอะ | 6-8GB |
| Modded (Forge/Fabric) | modpack ขนาดใหญ่ | 8-16GB+ |
เซิร์ฟเวอร์ modded อย่าง modpack ใหญ่ ๆ กิน RAM มากกว่า vanilla หลายเท่าเพราะโหลด mod จำนวนมากและ generate โลกซับซ้อนกว่า
เลือก VPS ที่เหมาะกับ Minecraft
เนื่องจาก Minecraft พึ่งประสิทธิภาพ CPU ต่อคอร์ (single-thread) เป็นหลัก การเลือก VPS ควรมองที่ความเร็ว CPU ต่อคอร์มากกว่าจำนวนคอร์เยอะ ๆ ที่ AsiaGB มี VPS Linux เริ่มต้น 500 บาท/เดือน ใช้สตอเรจ SSD บริหารผ่าน DirectAdmin และมี uptime 99% ซึ่งเพียงพอสำหรับเซิร์ฟเวอร์ขนาดเล็กถึงกลาง โดยควรเลือกแพ็กเกจที่ให้ RAM เผื่อ OS แล้วยังเหลือให้ heap ตามตารางด้านบน
ขั้นตอนจูนแบบสรุป
- ประเมินจำนวนผู้เล่นและประเภทเซิร์ฟเวอร์ เลือก heap จากตาราง
- ตั้ง
-Xmsเท่ากับ-Xmxเสมอ และเผื่อ RAM ให้ OS 1-2GB - ใส่ Aikar's Flags ทั้งชุด (ปรับตามขนาด heap ถ้าเกิน 12GB)
- รันแล้วเฝ้าดู TPS/MSPT ด้วย /spark
- ถ้ายังแลคทั้งที่ RAM พอ ให้มองหาปัญหา CPU-bound แทนการเพิ่ม RAM
การจูนที่ถูกต้องไม่ใช่การอัด RAM มากที่สุด แต่คือการจัดสรรให้พอดีและปล่อยให้ G1GC ทำงานได้อย่างมีประสิทธิภาพ ควบคู่กับ CPU ที่แรงต่อคอร์
คำถามที่พบบ่อย (FAQ)
ควรตั้ง Xms และ Xmx ให้เท่ากันไหม?
ควรตั้งให้เท่ากันเสมอ เพื่อให้ JVM จอง heap ครบตั้งแต่เริ่ม ไม่ต้องขยายกลางทางซึ่งทำให้เกิด pause กระตุก
ให้ RAM เยอะ ๆ แล้วเซิร์ฟเวอร์จะลื่นขึ้นจริงไหม?
ไม่จริงเสมอไป heap ที่ใหญ่เกินทำให้ GC pause ยาวขึ้น และถ้าปัญหาเป็น CPU-bound การเพิ่ม RAM จะไม่ช่วยเพิ่ม TPS เลย
TPS กับ MSPT ต่างกันอย่างไร?
TPS คือจำนวน tick ต่อวินาที เป้าหมาย 20 ส่วน MSPT คือเวลาต่อ tick ควรต่ำกว่า 50ms ถ้า MSPT เกิน 50ms แสดงว่า TPS กำลังตก
จะรู้ได้อย่างไรว่าแลคเพราะ RAM หรือเพราะ CPU?
ใช้ /spark หรือ /timings ตรวจสอบ ถ้า RAM เหลือและไม่มี GC pause ยาวแต่ TPS ยังตก แปลว่าเป็น CPU-bound ต้องลดภาระเธรดหลัก
พร้อมเปิดเซิร์ฟเวอร์ Minecraft ของคุณแล้วหรือยัง?
AsiaGB VPS Linux (SSD, DirectAdmin, uptime 99%) เริ่มต้น 500 บาท/เดือน ดาต้าเซ็นเตอร์ไทย/สิงคโปร์ ปิงต่ำ เหมาะกับเซิร์ฟ Minecraft ทุกขนาด
ดูแพ็กเกจ VPS