java - Red Hat Linux 中的低 Java 单进程线程限制

标签 java linux redhat

我在使用 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

This seems to be unaffected by things such as the number of threads in use by other processes or users or the total amount of memory the system is using at the time. JVM settings like Xms, Xmx, and Xss don't seem to change anything either (which is expected, considering the issue seems to be with native OS thread creation).

The output of "ulimit -a" is as follows:

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

The user process limit does not seem to be the issue. Searching for information on what could be wrong has not turned up much, but this post seems to indicate that at least some Red Hat kernels limit a process to 300 MB of memory allocated for stack, and at 10 MB per thread for stack, it seems like the issue could be there (though it seems strange and unlikely as well).

I've tried changing the stack size with "ulimit -s" to test this, but any value other than 10240 and the JVM does not start with an error of:

Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

I can generally get around Linux, but I really don't know much about system configuration, and I haven't been able to find anything specifically addressing this kind of situation. Any ideas on what system or JVM settings could be causing this would be appreciated.

Edits: Running the thread-limit program mentioned by plinth, there was no failure until it tried to create the 1529th thread.

The issue also did not occur using a 1.4 JVM (does occur with 1.6.0_02 and 1.6.0_04 JVMs, can't test with a 1.5 JVM at the moment).

The code for the thread test I'm using is as follows:

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 模型。

最佳答案

你看过this resource了吗? ? 它声明您应该能够运行 thread-limit 来找到最大线程数,并且可以通过编译 glibc 对其进行调整。

关于java - Red Hat Linux 中的低 Java 单进程线程限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/116640/

相关文章:

c# - 使用证书公钥验证 java 中的签名

java - 两个线程同时访问同一个ArrayList?

c - 更好的 sprintf?

c++ - 意外的 std::io_base::failure 异常

jboss - 事件锁定未按预期工作

java - volatile 读取冲突

java - Java 中向链表追加内容

linux - 管道到 AWK 忽略包含未知主机的行

regex - 使用 sed 和正则表达式解析无线调查的 iwlist 命令输出

redhat - 从源代码构建 OpenLDAP 而缺少 BerkelyDB