Recently, if you want to test the maximum number of concurrencies under Openfire, you need to open a large number of threads to simulate the client. I have always been puzzled about how many threads a JVM instance can open, so I plan to test it out and find the following factors that affect the number of threads:
-Xms | Intial java heap size |
-Xmx | maximum java heap size |
-Xss | the stack size for each thread |
System Limitations | The maximum number of threads that can be opened in the system |
The test program is as follows: Java code:
import java.util.concurrent.atomic.AtomicInteger; public class TestThread extends Thread { private static final AtomicInteger count = new AtomicInteger(); public static void main(String[] args) { while (true) (new TestThread()).start(); } @Override public void run() { System.out.println(count.incrementAndGet()); while (true) try { Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { break; } } } Test environment: System: Ubuntu 10.04 Linux Kernel 2.6 (32-bit)
Memory: 2G
JDK: 1.7
Test results:
Ø No system limitations considered
-Xms | -Xmx | -Xss | result |
1024m | 1024m | 1024k | 1737 |
1024m | 1024m | 64k | 26077 |
512m | 512m | 64k | 31842 |
256m | 256m | 64k | 31842 |
When the number of threads created reaches 31,842, no threads can be created in the system.
From the above test results, it can be seen that increasing heap memory (-Xms, -Xmx) will reduce the number of threads that can be created, and increasing thread stack memory (-Xss, the minimum value of this parameter in 32-bit systems is 60K) will also reduce the number of threads that can be created.
Ø Combined with system limitations
The limit of the number of threads 31842 is determined by the maximum number of threads that the system can generate: /proc/sys/kernel/threads-max, but its default value is 32080. Modify its value to 10000: echo 10000 > /proc/sys/kernel/threads-max, and the modified test results are as follows:
-Xms | -Xmx | -Xss | result |
256m | 256m | 64k | 9761 |
In this case, does it mean that as many threads as possible can be configured? Make another modification: echo 1000000 > /proc/sys/kernel/threads-max, the modified test results are as follows:
-Xms | -Xmx | -Xss | result |
256m | 256m | 64k | 32279 |
128m | 128m | 64k | 32279 |
It is found that the number of threads will no longer increase after reaching 32279. After checking, the maximum number of pids that can be created by a 32-bit Linux system is 32678. This value can be modified through /proc/sys/kernel/pid_max (the modification method is the same as threads-max), but in the 32 system, this value can only be changed to smaller and cannot be larger. When threads-max is certain, the test results for modifying pid_max are as follows:
pid_max | -Xms | -Xmx | -Xss | result |
1000 | 128m | 128m | 64k | 582 |
10000 | 128m | 128m | 64k | 9507 |
The situation on Windows should be similar, but the number of threads that can be created on Windows may be smaller than Linux. Servers based on thread model are always limited by the number of threads.
The maximum number that can be generated in JVM is affected by the heap memory size of the JVM, the Stack memory size of Thread, and the maximum number of threads that the system can create (the implementation of Java threads is based on the threading mechanism of the underlying system, _beginthreadex under Windows, and pthread_create under Linux). The specific amount can be estimated based on the maximum memory that the Java process can access (generally 2G on 32-bit systems), heap memory, and Thread's Stack memory.
sequence:
Tested on 64-bit Linux system (CentOS6, 3G memory), I found that there is another parameter that limits the number of threads: maxuserprocess (can be viewed through ulimita, the default value is 1024, and this value can be modified through ulimitu). This value is not limited in the above 32-bit Ubuntu test environment.
Modify threads-max, pid_max, maxuserprocess, all three parameters to 100000, -Xms, -Xmx as small as possible (128m, 64m), and -Xss as small as possible (104k at 64 bits, the value can be 128k). Predicted in advance in this test environment, the number of threads will only be limited to the memory size (3G) of the test environment. However, the actual test result is that when the number of threads reaches 32K (32768, the maximum number of created is about 33,000), the JVM throws a warning: Attempttoallocatestackguardpages failed, and then an OutOfMemoryError cannot create the local thread. After checking the memory, I found that there is still a lot of free time, so it should not be due to the memory capacity. Google's warning is fruitless. I don't know why, and it needs further research.
Step 2:
I accidentally discovered the article [7] today and tried it immediately. Sure enough, this factor will affect the number of thread creations. According to the description in the article, the number of /proc/sys/vm/max_map_count is doubled, from 65536 to 131072. The total number of threads created has reached 65000+. The computer basically has to be stuck (3G memory)... I briefly checked the function of this parameter, and the description in [8] is as follows:
“This file contains the maximum number of memorymapareasprocessmayhave.Memorymapareasareusedasaside-effect callingmalloc,directly bymmapandmprotect,andalso when loading shared libraries.
While most applications are needed less than that of the maps, certain programs, particularly mallocdebuggers, may consume the ass, eg, uptooneortwomapsperallocation.
Thedefaultvalueis65536."
OK, this problem has finally been solved completely. Finally, the factors affecting the number of Java threads are summarized:
Java virtual machine itself: -Xms, -Xmx, -Xss;
System Limitations:
/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process(ulimit-u),
/proc/sys/vm/max_map_count.
Summarize
The above is all about the simple test of jvm supporting maximum number of threads. I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out.