java - java OutOfMemoryException 创建新线程时,仅当活动线程数为 500 或以上时
问题描述
对于上下文,我正在运行一个修改过的 minecraft 服务器,其中一个 mods(computercraft)为您放置的每个块创建一个新线程。服务器在运行时只使用大约 15gb 的内存,但它有超过 30gb 的可用内存(-Xms8192M -Xmx32000M
),所以 OOME 真的没有意义。我确实在某个地方读到过,如果活动线程过多并且您尝试创建另一个线程,则会引发 OOME,这就是让我认为存在限制的原因
每当活动线程计数(使用 VisualVM 可见)达到 500 或更多时,它会OutOfMemoryException
在尝试启动新线程时抛出一个。我在互联网上找不到太多(我找到了一篇文章,但提到了 503 个线程,但他们提到的似乎没有任何帮助,而且我的服务器甚至无法超过 500)
我虽然这可能是 Docker 的问题(我使用翼手龙)所以我将 docker 的“TasksMax”变量设置为 Infinity,但这似乎没有帮助。我尝试降低堆栈大小(-Xss320k
在 Xms 位之前),但这没有帮助
我还检查了系统内存使用情况,以防有任何内存泄漏,但没有。它只使用大约 50% 的内存。当我ulimit -a
在linux中运行命令时,它显示的是:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 256816
max locked memory (kbytes, -l) 65536
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) 256816
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
创建新线程的示例是当新玩家加入时(因为每个玩家都有自己的 NetConnection)。这是崩溃堆栈跟踪的样子:
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:717)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1378)
at org.bukkit.craftbukkit.v1_6_R3.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:360)
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:831)
at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:332)
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:782)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:665)
at net.minecraft.server.ThreadMinecraftServer.run(SourceFile:583)
有谁知道是什么导致这个线程限制为 500?我修复它的唯一方法是强制杀死(thread.interrupt()
然后thread.stop()
)最新创建的计算机线程(它们对服务器的运行能力并不那么重要,但它给玩家带来了不便,不得不重新启动计算机。我不确定是什么计算机技术在这些线程中使用的监视器/锁定类型,因此杀死它们可能很危险)
我也尝试过“java.lang.OutOfMemoryError:无法创建新的本机线程”的解释,但这似乎也没有帮助
编辑:以防万一它帮助别人,我没有找到解决办法(增加线程限制)。我认为这可能是我用来运行服务器的限制(与docker有关)。我发现这是computercraft的并行API(又名多线程)的问题,所以我不得不禁用它(通过编辑pastebin api和文本编辑器保存/退出功能)
解决方案
推荐阅读
- excel - 工作簿关闭时访问工作表中的子
- android - 我们应该总是对片段内的上下文进行空检查吗?
- iptables - 将 BeagleBone Black 连接到互联网
- java - 无法将 IST 转换为 UTC
- java - Spring Boot 多对多重复记录
- visual-studio-code - VS Code 扩展:装饰上的点击事件
- jmeter - {__time(DD-MM-YYYY)} 用于保存 Jmeter 结果,日期返回如 32-03-2019,33-03-2019 等
- node.js - angular 4 / res.download 从 nodejs 后端
- python - 尽管覆盖了 input_shape 参数,但尝试在张量流对象检测 api 中导出推理时出现不完整的形状错误
- javascript - 从其他函数调用时推送将不起作用