แก้ “OutOfMemoryError: Java heap space” และ “Could not reserve enough space” บนเซิร์ฟเวอร์ Minecraft
มีปัญหาสามแบบที่ถูกเรียกว่า “out of memory” ถ้าเซิร์ฟเวอร์สตาร์ตไม่ขึ้นและพูดถึง object heap แปลว่าคุณขอ RAM ให้ Java มากกว่าที่เครื่องมี ถ้ามันรันแล้วแครชด้วย OutOfMemoryError แปลว่ามันต้องการมากกว่าที่คุณให้ หรือมีบางอย่างรั่ว ถ้ามันขึ้นแค่ “Killed” แปลว่าระบบปฏิบัติการปิดมัน
คุณเจอข้อผิดพลาดแบบไหน
| ข้อความ | ความหมาย |
|---|---|
| Could not reserve enough space for object heap | ตอนสตาร์ต: -Xmx มากกว่าหน่วยความจำที่มี หรือคุณใช้ Java แบบ 32 บิต |
| java.lang.OutOfMemoryError: Java heap space | ระหว่างรัน: heap เต็ม เซิร์ฟเวอร์ต้องการหน่วยความจำมากขึ้นหรือโหลดน้อยลง หรือมีหน่วยความจำรั่ว |
| GC overhead limit exceeded | Java ใช้เวลาเกือบทั้งหมดไปกับการเคลียร์หน่วยความจำ สาเหตุเดียวกับ heap เต็ม |
| “Killed” หรือ exit code 137 | ระบบปฏิบัติการหรือคอนเทนเนอร์ปิดเซิร์ฟเวอร์เพราะทั้งเครื่องหน่วยความจำหมด |
Could not reserve enough space for object heap
- ตรวจหน่วยความจำที่ว่าง บน Linux ให้รัน
free -hบน Windows ให้เปิด Task Manager - ลด -Xmx Java ใช้มากกว่า heap ดังนั้นบนเครื่องเล็กให้ตั้ง -Xmx ไม่เกินราวสามในสี่ของ RAM บนเซิร์ฟเวอร์ 4 GB ค่า 3G เป็นเพดานที่ปลอดภัย
- ใช้ Java แบบ 64 บิต เอาต์พุตของ
java -versionควรบอกว่า 64-Bit Java แบบ 32 บิตจองเฮปใหญ่ไม่ได้
java -Xms3G -Xmx3G -jar server.jar --nogui
ตั้ง -Xms ให้เท่ากับ -Xmx เพื่อให้เซิร์ฟเวอร์จองหน่วยความจำครั้งเดียวตอนเริ่ม
java.lang.OutOfMemoryError: Java heap space
- ให้หน่วยความจำเซิร์ฟเวอร์มากขึ้น ถ้าเครื่องมี ดู เซิร์ฟเวอร์ Minecraft ต้องใช้ RAM เท่าไร สำหรับขนาดตามประเภทเซิร์ฟเวอร์
- ลดภาระ ลด
view-distanceและsimulation-distanceใน server.properties เช่นเป็น 8 และ 6 - หาจุดรั่ว ติดตั้งปลั๊กอินหรือม็อด spark ปล่อยให้เซิร์ฟเวอร์รันจนหน่วยความจำสูง แล้วรัน
/spark heapsummaryมันแสดงรายการสิ่งที่ใช้หน่วยความจำมากที่สุด คลาสจากปลั๊กอินตัวเดียวที่อยู่บนสุดของรายการชี้ไปที่ตัวการ - อัปเดตหรือลบตัวการ หน่วยความจำรั่วมักถูกแก้ในปลั๊กอินเวอร์ชันใหม่ การให้หน่วยความจำเพิ่มแก่ปลั๊กอินที่รั่วแค่ยืดเวลาการแครชออกไป
- รีสตาร์ตตามตารางเวลา การรีสตาร์ตทุกวันซ่อนจุดรั่วช้าๆ จนกว่าคุณจะหาเจอ เป็นแค่ทางแก้ชั่วคราว ไม่ใช่การแก้จริง
“Killed” และ exit code 137
นี่ไม่ใช่ข้อผิดพลาดของ Java บน Linux ตัวฆ่าโพรเซสเมื่อหน่วยความจำหมด (out-of-memory killer) จะปิดโพรเซสที่ใหญ่ที่สุดเมื่อทั้งเครื่องหน่วยความจำหมด และคอนเทนเนอร์ก็ทำแบบเดียวกันที่ขีดจำกัดหน่วยความจำ ยืนยันได้ในล็อกเคอร์เนล:
sudo dmesg | grep -i "killed process"
วิธีแก้คือลด -Xmx เพื่อให้ Java รวมกับทุกอย่างบนเครื่องพอดีกับ RAM และปิดซอฟต์แวร์อื่นที่กินหน่วยความจำ เช่นฐานข้อมูลหรือเซิร์ฟเวอร์เกมตัวที่สอง ไฟล์ swap ขนาดเล็กเป็นตาข่ายนิรภัย แต่ไม่ใช่ตัวแทนของ RAM
ป้องกันไม่ให้กลับมาอีก
- เลือกขนาด heap จากประเภทเซิร์ฟเวอร์และจำนวนผู้เล่น แล้วดูการใช้งานจริงด้วย spark
- สร้างโลกล่วงหน้า เพื่อให้การสร้างชังก์ไม่ทำให้หน่วยความจำพุ่งขณะผู้เล่นสำรวจ
- อัปเดตปลั๊กอินและซอฟต์แวร์เซิร์ฟเวอร์อยู่เสมอ
โฮสต์เซิร์ฟเวอร์ Minecraft ของคุณในสิงคโปร์
ปิงต่ำสำหรับผู้เล่นในอินเดีย มาเลเซีย และอินโดนีเซีย บนคอร์ AMD EPYC ที่เร็ว พร้อม NVMe และการป้องกัน DDoS
