编辑

编辑

当我使用 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 服务器时遇到同样的问题,请尝试删除该修改。

相关内容