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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/116640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:04:51  来源:igfitidea点击:

Low Java single process thread limit in Red Hat Linux

javalinuxredhat

提问by ColinD

I'm experiencing an issue on a test machine running Red Hat Linux (kernel version is 2.4.21-37.ELsmp) using Java 1.6 (1.6.0_02 or 1.6.0_04). The problem is, once a certain number of threads are created in a single thread group, the operating system is unwilling or unable to create any more.

我在使用 Java 1.6(1.6.0_02 或 1.6.0_04)运行 Red Hat Linux(内核版本为 2.4.21-37.ELsmp)的测试机器上遇到问题。问题是,一旦在单个线程组中创建了一定数量的线程,操作系统就不愿意或无法再创建。

This seems to be specific to Java creating threads, as the C thread-limit program was able to create about 1.5k threads. Additionally, this doesn't happen with a Java 1.4 JVM... it can create over 1.4k threads, though they are obviously being handled differently with respect to the OS.

这似乎是 Java 创建线程所特有的,因为 C 线程限制程序能够创建大约 1.5k 个线程。此外,Java 1.4 JVM 不会发生这种情况……它可以创建超过 1.4k 个线程,尽管它们显然在操作系统方面的处理方式不同。

In this case, the number of threads it's cutting off at is a mere 29 threads. This is testable with a simple Java program that just creates threads until it gets an error and then prints the number of threads it created. The error is a

在这种情况下,它切断的线程数仅为 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).

这似乎不受其他进程或用户正在使用的线程数或系统当时使用的内存总量等因素的影响。Xms、Xmx 和 Xss 等 JVM 设置似乎也没有改变任何东西(这是意料之中的,考虑到问题似乎与本机 OS 线程创建有关)。

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

“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

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 postseems 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).

用户进程限制似乎不是问题。搜索有关可能出错的信息并没有发现太多,但是这篇文章似乎表明至少某些 Red Hat 内核将进程分配给堆栈的内存限制为 300 MB,每个线程为堆栈分配 10 MB,似乎就像问题可能存在一样(尽管这看起来很奇怪也不太可能)。

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:

我已经尝试使用“ulimit -s”更改堆栈大小来测试这一点,但是除了 10240 和 JVM 之外的任何值都不会以以下错误开始:

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.

我通常可以绕过 Linux,但我真的对系统配置知之甚少,而且我找不到任何专门解决这种情况的方法。关于什么系统或JVM设置可能导致这种情况的任何想法将不胜感激。

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).

使用 1.4 JVM 时也未出现此问题(使用 1.6.0_02 和 1.6.0_04 JVM 时确实会出现此问题,目前无法使用 1.5 JVM 进行测试)。

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) {
         }
      }
   }
}

If you run this with a 1.4 JVM it will hang when it can't create any more threads and require a kill -9 (at least it did for me).

如果您使用 1.4 JVM 运行它,它会在无法创建更多线程并需要 kill -9 时挂起(至少对我来说是这样)。

More Edit:

更多编辑:

It turns out that the system that is having the problem is using the LinuxThreads threading model while another system that works fine is using the NPTL model.

事实证明,出现问题的系统使用的是 LinuxThreads 线程模型,而另一个运行良好的系统使用的是 NPTL 模型。

采纳答案by ColinD

Updating the kernel to a newer version (2.6.something) with NPTL threading fixed this.

使用 NPTL 线程将内核更新到更新版本 (2.6.something) 解决了这个问题。

回答by plinth

Have you looked at this resource? It states that you should be able run thread-limit to find the maximum number of threads and can tweak it by compiling glibc.

你看过这个资源吗?它指出您应该能够运行 thread-limit 来找到最大线程数,并且可以通过编译 glibc 来调整它。

回答by Umut Uzun

The settings in /etc/security/limits.d/90-nproc.confmay be overriding your /etc/security/limits.confsettings. That may cause the system act in a different way shown in ulimit -u.

中的设置/etc/security/limits.d/90-nproc.conf可能会覆盖您的/etc/security/limits.conf设置。这可能会导致系统以 中所示的不同方式运行ulimit -u

https://bugzilla.redhat.com/show_bug.cgi?id=823030

https://bugzilla.redhat.com/show_bug.cgi?id=823030

回答by dsm

This is with Ubuntu Linux (1GB RAM)

这是 Ubuntu Linux (1GB RAM)

dsm@localhost:~$ javac ThreadTest.java 
dsm@localhost:~$ java ThreadTest 
8113
dsm@localhost:~$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
dsm@localhost:~$ 

回答by Tim Howland

Can you try it with the JRockit JVM? IIRC, it had a different threading model than the stock Sun JVM.

你能用 JRockit JVM 试试吗?IIRC,它具有与股票 Sun JVM 不同的线程模型。