Java java.lang.OutOfMemoryError "unable to create new native thread" or "Failed to create a thread"
Environment
- OpenJDK derivative
- Adoptium
- Azul
- Oracle
- Red Hat
- IBM JDK
Issue
-
Encountered the following exception in the JBoss server log using OpenJDK or Oracle JDK:
java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:597) ... -
The IBM javacore file shows the following:
1TISIGINFO Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" "Failed to create a thread: retVal -1073741830, errno 11" received -
The Oracle crash file reports the following:
# There is insufficient memory for the Java Runtime Environment to continue. # Cannot create GC thread. Out of system resources. [...]
-
ActiveMQ on broker throw java OOM error
-
The following in the OpenJDK or Oracle/Sun JDK fatal error log:
# Out of Memory Error (gcTaskThread.cpp:46), pid=5490, tid=139954866263808
Resolution
64-bit:
If the issue happens on 64-bit, the issue is typically resolved by increasing OS limits or decreasing system resource demand:
-
Increase OS limits on the number of threads:
-
Linux
- Set a higher ulimit for open files in
/etc/security/limits.confon Linux. For example:
soft nofile 1024 hard nofile 8192 or to set both hard and soft to the same value: - nofile 2048Note: Do not set it to an overly high value, as it can cause slowness. See https://access.redhat.com/solutions/4713351.
- Set higher ulimit for max user processes in
/etc/security/limits.confon Linux. For example:
soft nproc 2048 hard nproc 8192-
For RHEL 6, a modification to
/etc/security/limits.d/90-nproc.confis needed rather than/etc/security/limits.conf, refer to the following article for more detatails: Setting nproc in /etc/security/limits.conf has no effect in Red Hat Enterprise Linux 6. -
If the maximum number of threads will increase beyond the default allowed (32768) you will need to increase this limit in
/etc/sysctl.conf. This value is controlled by pid_max, and to double this value the following line would be added:kernel.pid_max = 65536 -
You may also need to update the kernel's
vm.max_map_count(default 65530) if JVM thread counts are exceeding this limit, but such a high legitimate thread count is rare.
- Set a higher ulimit for open files in
-
-
Decrease the number of threads.
- If you have applications that use JSF, try the following settings in their web.xml:
<context-param> <param-name>facelets.REFRESH_PERIOD</param-name> <param-value>-1</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>false</param-value> </context-param> -
Avoid running multiple copies of the same application by ensuring it's fully stopped before restarting.
-
In OCP 4.X, pls ref Unable to create more than 1024 Threads in OCP 4
-
In OCP 3.X, pls ref Introducing 'default pid limit' within docker to improve reliability of OpenShift Container Platform
-
Resolve downstream issues causing threads to build up or hang (e.g. a DB connection limit/bottleneck).
32-bit:
This issue is most commonly resolved by moving to 64-bit, where there is no memory split and no 4GB limit for address space.
If moving to 64-bit is not an option, the following are ways to avoid the issue on 32-bit:
-
Decrease the JVM process size:
- Explicitly set the thread stack size. The reason for this is that the default value can be 1024kB and a typical thread stack size of 128K or 256K is usually adequate. See How do I set Java thread stack size?.
- Decrease the amount of memory reserved for the heap and/or perm gen space.
- Upgrade from JDK 1.5 to JDK 1.6 or OpenJDK 1.6 to take advantage of the more efficient memory mapping of jar files that significantly reduces JVM memory consumption. JDK 1.5 memory maps entire jar files, whereas Content from weblogs.java.net is not included.JDK 1.6 and OpenJDK 1.6 only memory maps a central directory.
- Use a preferred or supported Windows service wrapper to ensure that options being used to limit the JVM process size are in fact being passed to the JVM. See What is the preferred method of running JBoss AS as a Windows Service?.
-
Increase the amount of available and/or contiguous address space:
- For 32-bit Windows, set the Content from technet.microsoft.com is not included.3GB switch.
- Content from java.sun.com is not included.Not supported as of JDK 1.6.
- Can potentially cause "out of kernel address space" issues under heavy network/io load.
- Uninstall any non-essential software to avoid shared libraries with preferred memory loading locations like Windows DLLs from fragmenting address space.
- For 32-bit Windows, set the Content from technet.microsoft.com is not included.3GB switch.
Root Cause
- Native virtual memory (address space) exhaustion and/or fragmentation.
- 64-bit
- Userspace virtual address allocations are limited to
overcomit_ratiopercent of physical memory due to overcommit being disabled withvm.overcommit_memory=2.
- Userspace virtual address allocations are limited to
- 32-bit
- More address space needs to be assigned
- 32-bit has 4GB theoretical maximum; however, not all the memory is available to a process. For example, the OS may be running a 2/2 memory split that is limiting the amount of memory able to be allocated to the process to 2GB. This is common for some versions of 32-bit Windows.
- 32-bit does not have enough address space for your use case.
- JVM process needs slimming
- Thread stack size is not set. The default thread stack size is typically much larger than needed.
- Running on Windows with the Content from forge.ow2.org is not included.JavaService wrapper is Content from jira.jboss.org is not included.known to have issues setting the thread stack size.
- Thread stack size is not set. The default thread stack size is typically much larger than needed.
- More address space needs to be assigned
- 64-bit
- OS resource limit soft value set too low
- Linux
- The open file limit imposed by the OS has been reached. In Java, every socket is a file.
- The maximum number of processes per user (
ulimit -u) limits the number of threads. - The number of sockets exceeds the open file limit (
ulimit -n). - The JVM process size is hitting the configured max memory size limit (
ulimit -m). - Java fails to create thread unexpectedly when launched through xinetd
- JBoss log has java.lang.OutOfMemoryError "unable to create new native thread" on SUSE
- Linux
- A thread leak is causing native virtual memory (address space) exhaustion or an OS resource limit to be reached.
- Thread leak when performing JMS operations in JBoss EAP
- JBoss has many threads named like "pool-161-thread-20"
- Growing amount of TimerThreads
- Many ldap Thread-### threads created in the JVM at once
- JBoss has many waiting ConnectionTable.Connection.Sender threads
- Thread exhaustion (OutOfMemoryError) with CXF AutomaticWorkQueueImpl as main suspect
- Many EJB client threads created during clustered remote EJB calls leads to OutOfMemoryError
- JBoss becomes unresponsive with many running threads that have no stack
- JBoss EAP leaks 'Remoting "management-client" task' threads
- EAP 7 becomes slow with many weld-preloader threads
- EAP 7 creates too many jaeger threads during start up
- Excessive amounts of SimpleAsyncTaskExecutor threads
- High amounts of I/O dispatcher threads accumulated in java application
- OCP 4.x is limiting threads to a 1024 max
- On Windows, this issue has been observed when physical memory is exhausted.
- A downstream limit/bottleneck is issues causing threads to build up or hang (e.g. a DB connection).
Diagnostic Steps
-
Is the process started with
systemd?systemdhas its own limits andulimitsare ignored. See How to set limits for services in RHEL and systemd. -
See "java.lang.OutOfMemoryError: unable to create new native thread" in Openshift Enterprise for troubleshooting applications deployed on OpenShift.
-
Analyze the OpenJDK (Adoptium, Oracle, Red Hat, etc.) fatal error log. Note: If a fatal error log is not created, the application is catching
OutOfMemoryError. -
Determine the amount of available physical memory, whether 32-bit or 64-bit, and the memory split for 32-bit.
-
Linux: Capture
meminfooutput to see available memory, whether 32 or 64-bit, and the memory split for 32-bit. On 64-bit systems HighTotal and HighFree will be 0. On 32-bit systems, LowTotal will indicate the memory split (e.g. if it is approx 1GB, it is a 3/1 split).cat /proc/meminfo > meminfo.txt -
Solaris: Run the attached This content is not included.meminfo_solaris.sh script. Output will be sent to
meminfo.out.bash ./meminfo_solaris.sh
-
-
If 32-bit, determine address space allocation from the fatal error log:
vi hs_err_pid<pid>.logand remove heading and tailing logs and only leavemmapdata in the "Dynamic libraries" section.awk '{ print $1 }' hs_err_pid<pid>.log > mmap.txt- Create the following script
run.sh:
#!/bin/bash awk $([[ $(awk --version) = GNU* ]] && echo --non-decimal-data) -F- ' BEGIN {OFS = FS; sum = 0} { $1 = sprintf("%d", "0x" $1) $2 = sprintf("%d", "0x" $2) sum = sum + ($2 - $1) } END { printf "%d bytes, %d MiB\n", sum, sum / (1024 * 1024) }' mmap.txt- Run the script
run.shand check if the address space allocated is next the maximum for the OS and 32-bit. For example:
$ sh ./run.sh 4294889472 bytes, 4095 MiB -
Is the Java application running in a dedicated environment, or are there other applications (e.g. colocated JBoss instances) and/or services (e.g. a database) competing for available memory?
-
Is the Java application running on dedicated physical hardware, or on a guest OS in a virtual environment?
-
What JVM options are being used
-
Enable garbage collection logging and analyze it to see if the maximum heap size and/or perm gen space can be decreased.
-
Check if the thread stack size is being explicitly set. The default thread stack size is typically much larger than needed. See Java default thread stack size.
-
Get a thread dump to see if something is spawning threads uncontrollably.
-
Determine the limits for the process. For example, on Linux:
cat /proc/<pid>/limits > limits.txt. Check the "soft values". -
Linux/Solaris: To see if the "max user processes" limit is being exceeded, compare
ulimit -uoutput (run as the user running JBoss) to the number of threads in the thread dump to see if the max user processes limit is being exceeded.-
ps -eLfoutput can easily show all running threads and processes on RHEL. Count how many threads are under the JBoss user. For example:cat ps.txt | grep "^jbossas" | wc -l -
Check the sosreport for the number of threads for the Java user: For example:
grep "jbossas" sosreport/sos_commands/process/ps_auxwwwm | wc -l 1029Note: The result will be slightly larger number than the actual number of threads due to the nature of
ps_auxwwwmoutput, where every process has a summary entry, so even a process with a single thread has 2 entries.
-
-
The fatal error log will show the
nprocvalue:rlimit: STACK 10240k, CORE 0k, NPROC 1024, NOFILE 4096, AS infinity- Check the
nprocvalue of the running process:cat /proc/<JBOSS_PID>/limits. What does it show for "Max processes"? If it is different than expected, the configuration values are not being picked up. The limits are inherited from your interactive login (i.e., your shell process). To ensure the latest settings, start a new login shell as that user and ensure you see what you want withcat /proc/$$/limits("$$" gets expanded to your current shell PID). See How to set limits (ulimit) for services in RHEL6 and older with upstart, sysvinit.
- Check the
-
Linux/Solaris: Compare
ulimit -nandnetstatoutput to see if the number of sockets is exceeding the open file limit. -
Test if
ulimitsettings need to be changed or added by compiling the attached This content is not included.ThreadTest class on the box running the Java application (javac ThreadTest.java), then run it as the user that the Java application is run under, passing in values such as 1500, 3000, 5000, and 10,000 and using the same JVM options used to start the Java applicaton. Does the script complete? If not, what number does it stop on? For example:java -server -Xss128k -Xms1024M -Xmx1024M -XX:PermSize=128M -XX:MaxPermSize=128M -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+UseParallelOldGC -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 ThreadTest 5000 -
Test running the Java application as root to determine if the issue is
ulimitrelated, as by default everything for root isunlimited. -
Use the following formula to determine approximately how many threads can be created:
Number of Threads = (MaxProcessMemory - JVMMemory - ReservedOsMemory - OtherPrograms) / (ThreadStackSize) -
If the Java application is being started with a Windows service wrapper, test to see if the issue can be reproduced when the Java application is started outside the wrapper.
-
Solaris: Ask if the JVM is running on a Solaris zone.
-
Solaris: Even if the JVM is running in 32-bit mode,
sun.arch.data.model: 32, Solaris can map 4GB per process, contrary to Windows and Linux. -
Sun JDK 1.5 update 7 and 1.6: Add the following JVM option to capture
pmapoutput when OutOfMemoryError happens to see address space information:-XX:OnOutOfMemoryError="pmap %p > pmap.out"Setting that in run.conf for JBoss can break parsing of the JAVA_OPTS being applied so in this case set it directly in run.sh instead:
while true; do if [ "x$LAUNCH_JBOSS_IN_BACKGROUND" = "x" ]; then # Execute the JVM in the foreground "$JAVA" -XX:OnOutOfMemoryError="\"pmap %p > pmap.out\"" $JAVA_OPTS \ -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" \ -classpath "$JBOSS_CLASSPATH" \ org.jboss.Main "$@" JBOSS_STATUS=$? -
On Windows, use Content from technet.microsoft.com is not included.Content from technet.microsoft.com is not included.http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx to get the address space layout of a process.
-
Determine address space limits by testing different max heap sizes with
java -version. The address space for the max heap size is reserved by the JVM on startup, but just the min heap size is allocated (RAM). For example:
$ java -Xms128M -Xmx2048M -version
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02)
Java HotSpot(TM) Client VM (build 1.5.0_16-b02, mixed mode)
$ java -Xms128M -Xmx3036M -version
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Note: Apparently the HP JVM has a throttle and just sets Xmx to the max possible value if you set Xmx higher than is physically possible.
- Windows: Check if physical memory is exhausted. There have been cases and Red Hat support has reproduced this error on 64-bit Windows when RAM is exhausted.
JBoss
- Inspect OS and JVM version and architecture information:
boot.logContent from jira.jboss.org is not included.starting in JBoss EAP 4.2 CP07 and EAP 4.3- 'server.log
starting in JBoss EAP 6.1.0 (requiresorg.jboss.as.configset toDEBUG` level)
- Inspect JVM options:
- Beginning of the console log
boot.logContent from jira.jboss.org is not included.starting in JBoss EAP 4.2 CP07 and EAP 4.3- 'server.log
starting in JBoss EAP 6.1.0 (requiresorg.jboss.as.configset toDEBUG` level)
- Test a typical thread stack size of 128k - 256k.
- If RHEL, get a
sosreport- Check
lsoffor open file descriptors - Check for multiple copies of the same application running
- Check
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.