Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hitting low Java thread limit (503 threads)

I have yet another Java thread limit question but I'm only talking about a paltry 500 threads or so and I can't find what limit I'm hitting. In fact - it seems to occur at a limit of 503 threads i.e. it looks like creating thread 504 yields the dreaded:

javax.ws.rs.ProcessingException: java.lang.OutOfMemoryError: unable to create new native thread
        at org.glassfish.jersey.client.JerseyInvocation.submit(JerseyInvocation.java:980) [jersey-client-2.25.jar:na]
        at org.glassfish.jersey.client.JerseyInvocation.submit(JerseyInvocation.java:889) [jersey-client-2.25.jar:na]
        at org.glassfish.jersey.client.JerseyInvocation$AsyncInvoker.method(JerseyInvocation.java:669) [jersey-client-2.25.jar:na]

Environment details:

  1. AWS t2.medium EC2 instance.
  2. Java(TM) SE Runtime Environment (build 1.8.0_111-b14) with Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode). Also reproduced on update u211.
  3. Using SLES 15.
  4. 4 GB on my testing server
  5. Seeing similar results on a production server which is a t2.large EC2 instance (8GB RAM).

ulimit -a output:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15743
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 15743
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Observations:

  1. It appears that it's network IO threads causing this issue. There are a number of thread pools that take care of various bits of application logic and they're fine. It's just when doing a lot of network I/O that a few more threads are created (depending on the load) and that's when the issue comes up.
  2. Limit appears to be 503 threads for the application (as reported by VisualVM and JConsole). If we load test and remain under 503 threads things are fine. If we hit 503 threads then we get the OOM messages and no more threads are created. This is far beneath normal thread/process limits which come up in similar questions on SO. Also, we're not creating 1000's of threads in some thread leak scenario. We really are trying to intentionally create > 503 threads.
  3. Reproducible with -Xss set to default (1MB), 512k and 2M - all variations top out at 503 threads i.e. this appears to not be a physical memory limit but some counter limit.
  4. Memory usage as reported by top doesn't go over ~70%.

I can provide a thread dump and NMT output but they don't seem to show anything out of the ordinary. They just show the 503 existing threads and heap allocation etc.

All the questions I've seen are to do with:

  1. actual, erroneous thread leaks or
  2. legitimate situations with 1000's of threads,
  3. rather small ulimit values.

None of these apply to my situation.

I did see this question which seemed to indicate that some obscure setting actually overrides/imposes a limit less than that shown using ulimit but the question and links were regarding RedHat. Is there a similar setting somewhere for SLES?

Basically I'd like to know - what's going on? Why can't I create a 504th thread?

like image 873
user5860663 Avatar asked Jun 12 '19 21:06

user5860663


People also ask

How many threads Java can handle?

Each JVM server can have a maximum of 256 threads to run Java applications. In a CICS region you can have a maximum of 1024 threads. If you have many JVM servers running in the CICS region, you cannot set the maximum value for every JVM server.

How can I increase the maximum number of JVM threads?

You can change these values by (temporal) running ulimit command or (permanent) editing /etc/security/limits. conf . This value is the system-global (including non-JVM processes) maximum number of threads. Check cat /proc/sys/kernel/threads-max , and increase if necessary.

What is the minimum number of threads in a Java program?

Every java application has at least one thread - main thread.

How many threads can run at once?

A single CPU core can have up-to 2 threads per core. For example, if a CPU is dual core (i.e., 2 cores) it will have 4 threads.


1 Answers

Turns out it was a systemd issue.

systemd introduced a limit on the number of threads for a single process which defaulted arbitrarily to 512 threads. I think our 503 limit in testing was actually

  503 counted threads
+ 9 other threads not counted
= 512 thread limit.

Setting DefaultTasksMax=infinity in /etc/systemd/system.conf solved this issue (this did require a reboot of our box).

We're actually running an initd service which is supported on systemd via systemctl. This means we couldn't set a different limit for just our service and had to resort to setting the global limit for all services.

like image 150
user5860663 Avatar answered Sep 21 '22 17:09

user5860663