29

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.

Lii
  • 11,553
  • 8
  • 64
  • 88
Craig Locke
  • 755
  • 4
  • 8
  • 12

7 Answers7

40

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
flob
  • 3,760
  • 2
  • 34
  • 57
  • lol ... a single thread will most certainly NOT use 512kb, you're confusing quite a few terms there – specializt Mar 30 '16 at 09:41
  • @specializt For a 1.5 JVM it was 512kb, according to the [Oracle hotspot faq on threads and oom](http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom) it is now as of 1.6+ a default of 320kb for a 32bit jvm on Linux & Windows. – flob Mar 30 '16 at 10:22
  • @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. – flob Mar 30 '16 at 10:39
  • `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 : https://msdn.microsoft.com/en-us/library/windows/desktop/ms686774.aspx but ... hey ... i guess sun/oracle developers arent "good with WINAPI" :) – specializt Mar 31 '16 at 09:15
  • @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.`](http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom) 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. – flob Mar 31 '16 at 09:36
  • the JVM uses weird defaults, on my current machine and OS (Win10 x64) the granularity is 0xFFFF+1 bytes for both x86_32 and x86_64. Just sayan. – specializt Mar 31 '16 at 10:13
15

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.

Jay
  • 26,876
  • 10
  • 61
  • 112
8

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

Maurice Perry
  • 32,610
  • 9
  • 70
  • 97
  • 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 Mar 30 '16 at 09:44
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;
}
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
ray
  • 31
  • 2
  • 5
    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. – Richard Chambers Nov 07 '17 at 18:53
  • 1
    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. – Jon Strayer Jul 09 '20 at 15:08
3

Millions

Well, millions if using virtual threads found in Project Loom technology being developed for future versions of Java.

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

Experimental builds of Project Loom based on early-access Java 18 are available now. The team seeks feedback.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
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();
    }
  }
}
Igor Dvorzhak
  • 4,360
  • 3
  • 17
  • 31
Rahul Sharma
  • 91
  • 1
  • 5
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.

Always Asking
  • 243
  • 2
  • 8