当我使用 Java 启动修改后的 Minecraft 服务器时,出现以下错误:
java.lang.OutOfMemoryError: unable to create new native thread
所以我的第一个猜测是,也许有些东西创建的线程太多,超出了限制,但服务器只创建了大约 50 个线程,导致我机器上的总线程数从 420 个增加到 470 个,这远远没有达到我的限制。我也不认为内存应该是一个问题,因为我给了我的服务器大约 8 GB,这应该足以启动。
这是我用来启动服务器的 java 命令:
java -server -XX:PermSize=512M -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -jar forge.jar -Xms8G -Xmx8G nogui -Dfml.queryResult=confirm
我使用以下命令来计算线程总数
ps -eo nlwp | tail -n +2 | awk '{ num_threads += $1 } END { print num_threads }'
正如所描述的这里。
我多次手动执行该命令,在服务器崩溃之前,线程数为 470。因此,除非服务器在一秒内创建超过 70 万个线程,否则不应该超过该限制。
在服务器崩溃之前,我的 bash 给出了以下错误:
-bash: fork: retry: Resource temporarily unavailable
这让我相信,确实已经达到了某种限制,而且问题不仅仅存在于虚拟机内部。
我的服务器有 32 GB 的 RAM,并且根据 top,java 进程的内存使用率低于 6%,也就是少于 2 GB,因此 vm 应该有足够的剩余内存。
根据此故障排除,OutOfMemoryError 的另一个含义可能是没有足够的内存来创建新线程,但由于我总共 32GB 的内存中只使用了 6 个,所以这也不应该是问题。
那么,由于线程数远低于限制,并且剩余足够多的内存(在虚拟机和系统的其余部分),还可能是什么问题呢?
以下是当前设置的限制:
mc@h*******:~$ ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 772691
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 772691
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
我的Java版本:
mc@h*******:~$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
我的 Ubuntu 版本:
mc@h*******:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.1 LTS
Release: 18.04
Codename: bionic
我尝试使用 创建线程转储jstack -l <PID> >> threaddump.log
。当服务器启动且一切仍正常运行时,日志文件如下所示:
Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new native thread
当服务器几乎完成启动时(服务器因 OutOfMemoryError 崩溃之前不久),日志如下所示:
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# An error report file with more information is saved as:
# /home/mc/hs_err_pid24081.log
我已经上传了错误日志这里。
答案1
由于重新安装 Oracle JDK 没有帮助,我尝试了 OpenJDK,并且成功了。OutOfMemoryErrors 现在消失了,一切都按预期运行。
编辑
看起来,切换 JDK 只是暂时起到了作用。但我刚刚发现了问题的真正根源。看起来,OutOfMemoryError 是由我尝试的两个 modpack 中的特定 mod 引起的。我仍然不知道,在没有增加线程数或内存满的情况下,OOME 是如何发生的,但无论如何。
导致问题的模型是星界魔法(版本 1.12.2-1.9.4)。因此,如果您在使用修改后的 minecraft 服务器时遇到同样的问题,请尝试删除该修改。