我在使用Java 1.6(1.6.0_02或1.6.0_04)运行Red Hat
Linux(内核版本为2.4.21-37.ELsmp)的测试计算机上遇到问题。问题是,一旦在单个线程组中创建了一定数量的线程,操作系统将不愿意或无法创建更多线程。
这似乎是特定于Java创建线程的,因为C线程限制程序能够创建约1.5k线程。此外,Java 1.4
JVM不会发生这种情况……它可以创建超过1.4k的线程,尽管显然它们在操作系统方面的处理方式有所不同。
在这种情况下,它截断的线程数仅为29个。这可以用一个简单的Java程序进行测试,该Java程序仅创建线程直到出现错误,然后打印其创建的线程数。错误是
java.lang.OutOfMemoryError:无法创建新的本机线程
这似乎不受其他进程或用户正在使用的线程数或系统当时正在使用的内存总量等因素的影响。像Xms,Xmx和Xss这样的JVM设置似乎也没有任何改变(考虑到问题似乎与本机OS线程创建有关,这是可以预期的)。
“ ulimit -a”的输出如下:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) 4
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited
用户进程限制似乎不是问题。搜索有关可能出错的信息的信息并没有太多,但是这篇文章似乎表明至少有一些Red
Hat内核将进程限制为分配给堆栈的300 MB内存,并且每个线程分配10 MB的内存,似乎这样的问题就可能存在(尽管看起来很奇怪,也不太可能)。
我尝试使用“ ulimit -s”更改堆栈大小以进行测试,但是除10240和JVM之外的任何其他值都不会以以下错误开头:
Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.
我通常可以绕过Linux,但是我对系统配置的了解并不多,而且我还没有找到专门解决这种情况的任何东西。关于可能导致此问题的系统或JVM设置的任何想法将不胜感激。
编辑 :运行由提到的线程限制程序的底座,也没有失败,直到它试图创建第一千五百二十九线程。
使用1.4 JVM时也不会发生此问题(在1.6.0_02和1.6.0_04 JVM中会发生,目前无法在1.5 JVM中进行测试)。
我正在使用的线程测试代码如下:
public class ThreadTest {
public static void main(String[] pArgs) throws Exception {
try {
// keep spawning new threads forever
while (true) {
new TestThread().start();
}
}
// when out of memory error is reached, print out the number of
// successful threads spawned and exit
catch ( OutOfMemoryError e ) {
System.out.println(TestThread.CREATE_COUNT);
System.exit(-1);
}
}
static class TestThread extends Thread {
private static int CREATE_COUNT = 0;
public TestThread() {
CREATE_COUNT++;
}
// make the thread wait for eternity after being spawned
public void run() {
try {
sleep(Integer.MAX_VALUE);
}
// even if there is an interruption, dont do anything
catch (InterruptedException e) {
}
}
}
}
如果您使用1.4 JVM运行此程序,它将在无法创建更多线程并需要kill -9时挂起(至少对我而言是如此)。
更多编辑:
事实证明,出现问题的系统正在使用LinuxThreads线程模型,而另一个运行良好的系统正在使用NPTL模型。
使用NPTL线程将内核更新为较新的版本(2.6.something)可以解决此问题。
所以我们有一些游戏服务器在我们的V服务器上运行(我说的这款有8Vcore、4.2GHz和32GB DDR4内存),例如Minecraft。我们的问题是服务器在大约640个线程的情况下耗尽了内存(它不关心栈大小,1024KB、512KB都是相同的结果)。那么有没有办法从我们的系统中得到更多的线程呢? Linux:Debian 9 Virtuozzo容器 Java: openjdk版本“1.8.023
问题内容: 我在实践中阅读Java Concurrency,并且有点与线程限制概念混淆。这本书说 当一个对象被限制在一个线程中时,即使该限制对象本身不是一个线程,这种使用也是自动的线程安全的 那么,当一个对象被限制在一个线程中时,没有其他线程可以访问它吗?那就是局限于线程吗?如何将对象限制在线程中? 编辑: 但是,如果我仍然想与另一个线程共享对象怎么办?假设在线程A完成对象O后,线程B想要访问O。
问题内容: 在我阅读的问题中,我们建议在进程上使用线程,因为线程速度更快。我决定使用程序的线程来编辑Wikipedia中某个类别的文章。该程序获取要编辑的文章列表,然后将文章划分为10个线程。这样一来,我每分钟进行6-7次编辑,这与我没有使用线程的速度相同。当我启动程序的多个实例并为每个实例指定要处理的类别时,我看到每个进程每分钟可以进行6-7次编辑(我用5个进程进行了测试)。 为什么我的流程更快
我正在尝试创建一个具有一定数量线程的ThreadPoolExector,但同时,我想控制池队列的大小。所以我使用完整的构造函数创建了执行器: 然而,这给了我一个非法辩论例外。如果我将构造函数更改为 它起作用了。如果我希望理想的线程数和最大线程数相同,为什么它不起作用呢。
问题内容: 一些 消息来源说,即使您没有操作系统上限和无限的RAM,您对Java中的线程数(例如15k或30k)也有硬性限制。我还听说,在Java 7中取消了此限制。两种说法都是正确的吗? 问题答案: 在Java虚拟机规范没有规定对线程数目的限制。它们通常受可用堆栈空间量的限制,因为每个线程都有自己的专用堆栈。(无法分配堆栈通常是在尝试创建新线程时触发OutOfMemory异常的原因。)我认为线程
在堆中,我们可以使用-Xms-Xmx来限制ram的使用。 在jvm堆之外,当使用NIO时,我们可以使用-XX: MaxDirectMemorysize。 但在这样的节目中 } 使用jvm选项 -Xms256m-Xmx256m-XX: MaxDirectMemorysize=128m 它运行良好。它不会发生错误。 -XX:MaxDirectMemorySize不工作? Java1.8OS:cento