问题
So according to most things I've read on the internet, the number of threads you can have in Java caps out around 10,000. However, in practice I can create nearly 500,000, at which point my computer becomes unresponsive. (The task manager goes a little funny - it starts claiming that though 99% of my 16 GB of memory is used, the highest-using program uses only ~300 MB. After everything stops responding, the fan quiets down, and the disk access light flashes only periodically, leading me to believe neither CPU nor disk is under heavy load.) I waited for about 15 minutes one test, and never got an exception (well, as far as I know).
For repeatability, I've (also) used the following code: https://github.com/jheusser/core-java-performance-examples/blob/master/src/test/java/com/google/code/java/core/threads/MaxThreadsMain.java as referenced here: https://dzone.com/articles/java-what-limit-number-threads .
I did, however, increase the upper limit on i
from 100 * 1000
to 1000 * 1000
, because it was successfully creating all the threads. One of the last messages it gave before the computer froze up was 440,000 threads: Time to create 4,000 threads was 1.002 seconds
- it looks like it was averaging around 2 seconds per 4000, though.
I am using Windows 10 Pro, version 1703. JRE: Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
The next highest thread count I know of is about 100k, https://stackoverflow.com/a/46697264/513038. Now, a lot of the claimed limits were given many years ago, but they're based on stack size vs memory, and at 500,000 threads in 16 GB RAM (even assuming ALL of it was used), that's 32kb per thread by default, which is supposedly less than the minimum stack size. If that were true, I'd at least expect more StackOverflowErrors during normal operation. Has the threading system changed silently in the past 10 years? (Or even in the past few months: one of the posts I referenced was made just a few months ago, April 2018.)
回答1:
Has the threading system changed silently in the past 10 years?
Nope. On Linux, MacOS and Windows, Java threads are implemented as native threads ... since a long time ago.
What has changed is the way that various different operating systems schedule native threads. The OS is where Java thread scheduling takes place, and where any hard limits on the number of threads supported will be enforced.
Basically, your tests try to see what happens when you try to use a pathologically large number of threads. The answer on Windows is that it breaks the OS.
And even if it didn't break the OS out-right, the chances are that for a Java application using 100,000's of threads:
- the JVM's resource usage (stack memory) would be terrible,
- native scheduler performance would be terrible, and
- the application performance would be terrible.
Huge numbers of threads is the wrong way to write a practical Java application. Actors may be a better solution, or maybe an ExecutorService (with a bounded thread pool) or a ForkJoin pool. It will depend on the application, and other factors.
In short, those tests you are running are not instructive for a properly designed Java application. The solution for applications that use huge numbers of threads is to rewrite them.
来源:https://stackoverflow.com/questions/51528790/java-thread-limit-jvm-9