对不规则的OutOfMemoryError进行故障排除:无法创建新的本机线程

时间:2019-06-23 16:59:01

标签: java multithreading out-of-memory

我有一个Ubuntu 16.04.5服务器,该服务器以root身份运行多个Java应用程序。应用程序经常从OutOfMemoryError: unable to create new native thread崩溃(大约每30分钟到1小时)。我注意到的是,应用程序并非单独崩溃,而是多个应用程序同时崩溃。

我不知道是什么原因造成的,我很难找到解决该问题所需的更改。

我关注了一些有关该错误的文章,并经历了多种可能的原因,但它们似乎不适用于我的情况:

修复线程创建率

应用程序会定期创建线程,但许多线程也会死亡。这意味着并发线程数永远不会超过10k。我通过生成线程转储和计数线程来检查是否对失控线程创建有问题,但是线程数从未超过前面提到的10k。

增加操作系统的线程限制

当我运行ulimit -u时,它将返回1546669

ulimit -u output

这应该足够了吧?

为计算机分配更多的内存

我使用了大约7GB的可用16GB RAM。这是我的顶部视图:

htop

其他信息

Java版本:

java version

该错误的完整错误堆栈跟踪:

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 de.domisum.lib.auxilium.util.java.ThreadUtil.createAndStartThread(ThreadUtil.java:126)
    at de.domisum.lib.auxilium.util.java.ThreadUtil.createAndStartThread(ThreadUtil.java:114)
    at de.domisum.lib.auxilium.run.RunNotifyOnTimeout.run(RunNotifyOnTimeout.java:32)
    at de.domisum.lib.auxilium.util.ticker.Ticker.tickWithTimeout(Ticker.java:119)
    at de.domisum.lib.auxilium.util.ticker.Ticker.run(Ticker.java:108)
    at java.lang.Thread.run(Thread.java:748)

来自应用程序的线程转储出现错误:thread dump

垃圾收集器日志:gc log1 gc log2 gc log3

1 个答案:

答案 0 :(得分:0)

将应用程序从虚拟服务器迁移到专用服务器后,问题消失了。

似乎虚拟化中存在与线程创建有关的错误。我还没有找到在虚拟服务器上运行应用程序时解决异常的解决方案。问题可能不在于虚拟化,而在于操作系统,操作系统设置或已安装的Java运行时。我尚未测试这些可能的原因,但我认为它们没有错。