First, and most importantly, Jetty 8 is EOL (End of Life)
Now, back to the threads ...
The max thread count on Jetty 9 is for the ThreadPool, which is a shared pool for all (non connector) things on the Jetty server.
The math for (max * acceptors) doesn't make sense for Jetty 9.
Also, when inspecting the JVM and looking at the raw count of threads, this information is meaningless without more context.
There are so many processes on a modern website that can spawn its own threads, who spawned them, why?
You'll need to understand, intimately, all of the technologies and libraries you are using first.
Then you'll want to get an accurate count of the types of threads that are in use. (use a combination of the thread names, stack patterns, and thread groups to get a clearer picture)
The description of the configuration for Jetty is incomplete, it tells us nothing of how you have organized Jetty, what you have for connectors, what options and module you are using, what you are doing with jetty, etc.
Its like you described 2 buttons on the dash of a automobile, read 1 gauge on the dash, for an anonymous and unnamed automobile and then started asking performance questions.
The information you have about thread stack size (ulimit -s) is OS specific, for applications built against the OS specific technologies.
This limit was was very important in the 32-bit era, but not much so in the 64-bit era we are in now (memory addressing is different).
Java threading isn't that strictly correlated.
$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: Fedora
Description: Fedora release 20 (Heisenbug)
total used free shared buffers cached
Mem: 32898260 6634384 26263876 53020 3130112 15169364
-/+ buffers/cache: 8334908 24563352
Swap: 16523260 2776 16520484
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 128428
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 10000
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
$ package fun;
public class ThreadMax
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String args)
new Thread(new Runnable()
public void run()
System.err.printf("New thread #%,d%n",count.incrementAndGet());
catch (InterruptedException ignore)
$ java -Xmx20g -cp target/classes/ fun.ThreadMax
New thread #1
New thread #2
New thread #9,437
New thread #9,438
Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated
That run could only get to 9,438 threads, using a whopping 2GB of memory.
Tip: keep your process monitor open before you run this class (its not very friendly on your system), you'll want a way to monitor memory use, and a way to kill the process.
I can drop the max memory down to -Xmx2g and get the same rough results (+/- 5 threads)
If I drop the max memory for the JVM down to -Xmx1g, then I get around 8,900-ish threads. (not much different considering the 50% reduction in max memory)
If I drop the ulimit -s to 4096, the max thread counts on 20g, 2g, and 1g are roughly the same as the ulimit -s 8192 settings.
Point is, the JVM threading isn't tied to the OS threading that tightly.
Trying to control JVM threading with OS thread settings wont do what you expect.