我在使用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.lang.OutOfMemoryError: unable to create new native thread
这似乎是由事不受影响如由其他进程或用户或该系统中的时间被使用的存储器的总量的使用的线程数.JVM设置,如X毫秒,XMX和XSS似乎没有任何改变任何东西(预计,考虑这个问题似乎是与本地操作系统线程创建).
"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模型.