The max number of thread in linux

Viewed 197

I used following code to test the max number of thread, but it's very queer.

import java.util.concurrent.atomic.AtomicInteger;

public class TestThread extends Thread {
    private static final AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) {
        try{
            while (true) {
                (new TestThread()).start();
            }
        } catch (Error | Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public void run() {
        System.out.println(count.incrementAndGet());
        while (true)
            try {
                Thread.sleep(Integer.MAX_VALUE);
            } catch (InterruptedException e) {
                break;
            }
    }
}

OS is ubuntu:18.04, the memory is 4G, number of processors is 2. JDK: openjdk1.8.0_252

java -Xss1m -Xms1024m -Xmx1023m TestThread

java -Xss512k -Xms1024m -Xmx1023m TestThread

java -Xss1m -Xms2048m -Xmx2048m TestThread

In the result, the number of threads are always equal around 10000th.

  1. why the result is the same.
  2. I set the -Xss1m in the command, does it mean each thread will have alone 1m memory? if it has alone memory, 10000th threads will have 10G memory, actually there just 4G memeory in the machine.
1 Answers

-Xss determines the maximum stack size for Java threads. When a thread starts, the operating system creates a region of virtual memory for the stack of this size, but the memory is not immediately allocated in physical RAM.

The physical pages are allocated lazily on the first memory access to the page. As long as your threads do not call deep methods, they do not use all the stack space. That's why only a few bottom stack pages are allocated in RAM, no matter what -Xss is set.

Linux enables memory overcommit by default. This means, it allows to commit more virtual memory than the amount of physical RAM (as long as this virtual memory is not actually backed by physical pages, like in your case).

So, in your case OutOfMemoryError is thrown not because of stack space, but due to one of the other OS limits:

  • ulimit -u
  • sysctl kernel.pid_max
  • sysctl kernel.threads-max

See also:

Related