如何在Linux开发笔记本上修复java.lang.OutOfMemoryError: unable to create new native thread
java.lang.OutOfMemoryError: unable to create new native thread in Local Java Performance Tests Great question! This error trips up a lot of folks running thread-heavy performance tests locally—let's break down why it's happening and walk through practical fixes to get your tests running smoothly before you deploy to the performance environment.
Why This Error Happens
First, let's clarify: this isn't about Java heap memory being full. It means your system can't create any more native OS threads for the JVM to use. Every Java thread maps to a native OS thread, and each one consumes system memory (mostly for the thread stack). There are hard limits on how many threads your user account and the system as a whole can create.
Step 1: Adjust System-Level Thread Limits (Ubuntu 16.04)
Check Current Limits
First, see what your current limits are:
- Check user-level thread limit:
ulimit -u(usually defaults to 1024 on Ubuntu) - Check system-wide thread limit:
sysctl kernel.threads-max
Increase User-Level Limits (Temporary & Permanent)
- Temporary fix (applies to your current shell session):
ulimit -u 8192 # Sets max user processes (threads) to 8192 - Permanent fix (persists across reboots):
Edit/etc/security/limits.confwith your favorite editor, then add these lines at the bottom (replaceyour_usernamewith your actual username):
Next, make sure PAM applies these limits: checkyour_username soft nproc 8192 your_username hard nproc 16384/etc/pam.d/common-sessionhas this line (add it if missing):
Log out and back in for the changes to take effect.session required pam_limits.so
Increase System-Wide Thread Limits
- Temporary fix:
sysctl -w kernel.threads-max=32768 - Permanent fix:
Edit/etc/sysctl.confand add:
Apply changes immediately with:kernel.threads-max=32768sysctl -p
Step 2: Optimize JVM Parameters
Reduce Thread Stack Size
By default, each Java thread uses a 1MB stack (64-bit JVM). You can reduce this to free up system memory for more threads:
java -Xss256k -jar your-test-app.jar # Sets stack size to 256KB per thread
Start with 256k or 512k—just make sure your tests don't hit a StackOverflowError (if you have deep recursion or large call stacks, you might need a bigger value).
Adjust Heap Memory Allocation
Don't allocate too much of your system's RAM to the Java heap—leave enough room for thread stacks and other system processes. For example, if your machine has 16GB of RAM, don't set -Xmx to 16GB:
java -Xmx8g -Xss256k -jar your-test-app.jar
Tweak these values based on your machine's available memory.
Step 3: Optimize Your Test Code & Thread Pools
Audit Thread Pool Configuration
If you're using Executors.newFixedThreadPool(n) with a huge n, that's probably overkill. Instead, use ThreadPoolExecutor to customize settings based on your task type:
- CPU-bound tasks: Keep max threads around
2 * number_of_cpu_cores(since each thread will be busy processing) - IO-bound tasks: You can use more threads, but don't go crazy—start with
4 * number_of_cpu_coresand adjust based on test results
Example of a custom thread pool:
int corePoolSize = Runtime.getRuntime().availableProcessors() * 2; int maxPoolSize = corePoolSize * 2; long keepAliveTime = 60L; ExecutorService executor = new ThreadPoolExecutor( corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<>() );
Reuse Thread Pools
Don't create a new thread pool for every test case—reuse a single global pool across your tests. Creating/destroying threads repeatedly wastes resources and can lead to unexpected thread spikes.
Check for Thread Leaks
Make sure your tests properly shut down thread pools after use with executor.shutdown() or executor.shutdownNow(). Leaked threads will hang around and consume system resources until your JVM exits. Use tools like JConsole or VisualVM to monitor thread count over time—if it keeps growing without dropping, you have a leak.
Verify the Fix
After making changes, run your tests and monitor thread usage:
- Use
top -H -p <your-jvm-pid>to see all threads for your JVM process - Use
jstack <your-jvm-pid>to list all Java threads and check for any unexpected ones
If you stop seeing the unable to create new native thread error, you're good to go!
内容的提问来源于stack exchange,提问作者Wojtek

