Red Hat Linux 中 Java 单进程线程限制较低
我在使用 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
这似乎不受其他进程或用户使用的线程数量或系统当时使用的内存总量等因素的影响。 Xms、Xmx 和 Xss 等 JVM 设置似乎也没有改变任何内容(这是预期的,考虑到问题似乎与本机操作系统线程创建有关)。
“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
用户进程限制似乎不是问题。 搜索有关可能出现问题的信息并没有发现太多,但是 这篇文章< /a> 似乎表明至少某些 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 设置可能导致此问题的想法将不胜感激。
编辑:运行 plinth,直到尝试创建第 1529 个线程才出现故障。
使用 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 模型。
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.
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.
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
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) {
}
}
}
}
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).
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 NPTL 线程将内核更新到较新的版本 (2.6.something) 修复了此问题。
Updating the kernel to a newer version (2.6.something) with NPTL threading fixed this.
这是 Ubuntu Linux (1GB RAM)
This is with Ubuntu Linux (1GB RAM)
你能用 JRockit JVM 尝试一下吗? IIRC,它具有与普通 Sun JVM 不同的线程模型。
Can you try it with the JRockit JVM? IIRC, it had a different threading model than the stock Sun JVM.
/etc/security/limits.d/90-nproc.conf
中的设置可能会覆盖您的/etc/security/limits.conf
设置。 这可能会导致系统以ulimit -u
中所示的不同方式运行。https://bugzilla.redhat.com/show_bug.cgi?id=823030
The settings in
/etc/security/limits.d/90-nproc.conf
may be overriding your/etc/security/limits.conf
settings. That may cause the system act in a different way shown inulimit -u
.https://bugzilla.redhat.com/show_bug.cgi?id=823030
您看过此资源吗?
它指出您应该能够运行 thread-limit 来查找最大线程数,并可以通过编译 glibc 来调整它。
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.