33

What are the maximum number of threads which can be maintained by the Java virtual machine?

I did not explain this in my original question, but I am trying to benchmark the JVM and would like to try and see how many threads it can concurrently maintain.

Creating threads in a loop until an exception is thrown is an option, however, I would like to know if there is a better way to do this.

3
  • 3
    It depends a lot on the underlaying operating system Commented Oct 11, 2011 at 13:33
  • 3
    Which JVM, which OS, how much memory, and under what conditions? It's hard to see how such a general question is going to be useful. Commented Oct 11, 2011 at 13:34
  • 1
    More than you can reasonably use. Commented Oct 11, 2011 at 13:37

7 Answers 7

43

There will be some limits imposed by your operating system and hardware configuration.

To raise the number of concurrent threads you should lower the default stacksize java -Xss 64k.

  • A Oracle 32 bit JVM will default to 320kb stack size per thread.
    • For a 32 bit JVM with 2gb of addressable memory this will give you a maximum of 6.5k threads.
  • A Oracle 64 bit JVM will default to 1M stack size per thread.
    • For each gigabyte of memory you would get 1024 threads using the defaults.
  • For Linux only:
    • ulimit -a will give you the configured limits, for user processes and memory
    • You will only get 32k unique PIDs in linux cat /proc/sys/kernel/pid_max - a maximum of 32k processes.
    • You will get only 255k threads cat /proc/sys/kernel/threads-max
Sign up to request clarification or add additional context in comments.

6 Comments

lol ... a single thread will most certainly NOT use 512kb, you're confusing quite a few terms there
@specializt For a 1.5 JVM it was 512kb, according to the Oracle hotspot faq on threads and oom it is now as of 1.6+ a default of 320kb for a 32bit jvm on Linux & Windows.
@specializt For a 64bit JVM it certainly defaults to 1M. So you will only get 1024 threads per gigabyte of memory if you stick to the defaults.
You can reduce your stack size by running with the -Xss option. For example: java -server -Xss64k and : 64k is the least amount of stack space allowed per thread -- which doesnt make much sense since the allocation granularity can be different from system to system : msdn.microsoft.com/en-us/library/windows/desktop/ms686774.aspx but ... hey ... i guess sun/oracle developers arent "good with WINAPI" :)
@specializt I don't understand what your point is? That there is no certainty about the stacksize in the JVM on Windows systems seemed out of scope to me, it is mentioned in the oracle docs as Note that on some versions of Windows, the OS may round up thread stack sizes using very coarse granularity. The possibility to use a smaller stacksize was included in my very first answer, with 64kb which seems to be the typical system's allocation granularity for windows according to the article linked by you.
|
17

Writing a loop that creates new threads until it blows up is the definitive way to find out. You might well see performance degrade terribly before it actually dies.

I don't know if there's any configuration parameter or other built-in limit in the JVM off the top of my head. I've never run into a limit in practice. Of course sooner or later you will run out of memory, maybe some other resource.

I suspect that there is not a limit on number of threads per se, but rather on resources associated with a thread. That is, you might see that you can have 10,000 threads if all of them are running just one small class with a few bytes of data each, but the number drops rapidly when they each have an array of 10 million strings.

Comments

8

The limit, if there is one, will be imposed by the operating system, not the jvm

2 Comments

actually, every conceivable, deterministic piece of software will always have hard limits on everything, including the JVM. Forever. x86_64 doesnt change that - in fact most software will have unplanned (and yet to be discovered) limits somewhere around 4GiB for a simpe reason : primitives like int still exist and are used everywhere ;). If one wanted to write software which is immune to these problems one would have to use BigInteger and whatnot - absolutely everywhere, even for loop indices.
@specializt Probably at least mostly true. There may be resource that don't need any kind of index or count, but most need SOME sort of handle. And that handle has to be stored somewhere, in some data type. Going to BigInteger increases the limit by a factor of many billions, but there'd still be a limit. Maybe at that point the limit is so large that you run out of other resources, like atoms on Planet Earth, before you hit it. Memory is getting cheap but I doubt that anyone has a computer with 2^64 bytes of RAM.
3

The real question should be not how many threads you can create but how many threads will run efficiently. Too many threads and you will cause thrashing, too few and less computation time.

First, question, how long to live is your thread. Short live threads are hardly worth the effort. Large computations on the other hand make perfect sense.

Second, how much memory will each thread consume. Take the amount of memory each thread requires and divided it by the amount of memory available. You should not create more threads than this.

Thirdly, how many CPUs do you have available. You should not create more threads than CPUs. In fact, you should consider at least one less than the number of threads. On a windows laptop with 4 CPUs, you should never have more than 3 Threads if efficient processing is required.

Finally, what does your thread do. If it reads and writes to a hard drive, then you can have more threads than the number of CPUs since it will have to wait for the device to respond. Consider the following method when deciding the number of threads:

public static int recommendedThreadCount() { int mRtnValue = 0; Runtime runtime = Runtime.getRuntime(); long maxMemory = runtime.maxMemory(); long mTotalMemory = runtime.totalMemory(); long freeMemory = runtime.freeMemory(); int mAvailableProcessors = runtime.availableProcessors(); long mTotalFreeMemory = freeMemory + (maxMemory - mTotalMemory); mRtnValue = (int)(mTotalFreeMemory/4200000000l); int mNoOfThreads = mAvailableProcessors-1; if(mNoOfThreads < mRtnValue) mRtnValue = mNoOfThreads; return mRtnValue; } 

2 Comments

I don't agree with the third point about limiting number of threads to the number of CPUs. Frankly that makes no sense at all especially if the thread is not CPU intensive and is doing a fair amount of waiting.
Exactly, but you see that bit of bad advice everywhere. If your threads are CPU bound then having more threads than cores doesn't help. But if they are I/O bound then you can have many more threads than cores. That's a parameter you need to tune to your work load.
2

Millions

Well, millions of simultaneous threads may be practical if using virtual threads found in Project Loom technology built into Java 21+.

See JEP 444: Virtual Threads.

More generally known in the industry as fibers, virtual threads under Project Loom run on top of the "real" platform/kernel threads that we already have in Java. Many virtual threads are mapped to each platform/kernel thread.

The virtual threads provide very cheap blocking. When the task on your background thread does file i/o, network calls, database access, logging, and so on, your code blocks, waiting for a response. Project Loom technology detects this blocking, "parks" (sets aside) that virtual thread, and assigns another virtual thread to continue its work on the platform/kernel thread. This parking and switching is very fast. As a result, threaded Java apps will generally see substantial gains in performance.

As a result, a JVM on mainstream computing hardware will be able to support millions of threads.

Caveats:

  • While virtual threads make blocking cheap, those cheap threads may be doing expensive work such as using much memory, many network ports, or database connections. So you may need to do some throttling of your tasks in such a case.
  • Virtual threads are appropriate for code that involves blocking, which is common in business-oriented apps. However, if the threaded work is CPU-bound such as processing video, then you should use a limited number of "real" platform/kernel threads rather than virtual threads.

Using virtual threads is a easy as switching your implementation of ExecutorService:

ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor() ; 

For more info, see this 2021-01-15 article. And see several very good video presentations and interviews by Ron Pressler and other team members. Study more recent materials as Loom has evolved.

2 Comments

This was old question about platform threads. Your answer does not make any sense as Virtual threads are NOT really threads.
@RamPrakash You are saying that someone interested in the limit of platform threads would have no interest in learning of the practically unlimited number of virtual threads available in Java 21+? And, how are virtual threads not threads? They execute code, have ThreadLocal, maintain a stack, and look like platform threads in debuggers.
1

Maximum thread limit mainly depends on hardware, OS and Java stack size.

The following factor plays a very important role to identify max thread limit:-

  1. Process virtual address limit (2^32 for 32-bit architecture and 2^64 for 64-bit architecture)
  2. Java stack size (can be determine by command java -XX:+PrintFlagsFinal -version | grep -iE 'ThreadStackSize'
  3. Max PID limit (can be determine by command "cat /proc/sys/kernel/pid_max")
  4. Max process limit ulimit -u

So max thread limit will be MINIMUM of ((process virtual address space/java stack size), Max PID limit, Max process limit)

e.g. if Max process limit is 2048 and it is minimum of all above mention three-factor then java process will not be able to create a thread more than that.

To verify it one can create simple java application in which he/she can create a thread in a loop and see how much it can go.

Example:

public class ThreadCountTest { private static final Object lock = new Object(); private static int counter = 0; public static void main(String[] _args) { while (true) { new Thread(new Runnable() { public void run() { synchronized(lock) { counter++; System.err.println("New thread #" + counter); } while (true) { try { Thread.sleep(3000); } catch (Exception e) { e.printStackTrace(); } } } }).start(); } } } 

Comments

0

Maximum number of threads can also be limited by the JVM implementation and cab be different from a Java virtual machine to another Java virtual machine. For example, in Jikes RVM an array is used to keep information about threads (See line 54 in the Jikes RVM Scheduler source code). In this case, the maximum number of threads cannot exceed the maximum size of an array in Java, which is about 2^32. But you are more likely to hit other OS limits or hardware limits before reaching 2^32 threads.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.