無法建立新的執行緒,因為每個執行都需要佔用一定的記憶體空間,當 JVM 向底層 OS 請求建立一個新的執行緒時,如果沒有足夠的資源分配就會拋出此錯誤,模擬無窮迴圈建立執行緒,直到 JVM 拋出錯誤, Java 147 增加了範例,並透過單元測試來驗證產出結果。
Table of Contents
ToggleJava OutOfMemoryError
Unable To Create New Native Thread
無法建立原生執行緒,設定 JVM Arguments。
-Xmn30m -Xms120m -Xmx120m
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- memory
| +- UnableToCreateNewNativeThreadTest.java
Java Heap Space
有以下幾種情境:
- 執行緒數超過 OS 最大限制。
- 執行緒數超過 kernel.pid_max。
- OS 記憶體不足。
max user processes
查看設置。
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) 3880
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
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) 3880
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
最大程序數,目前設置 3880
kernel.pid_max
查看目前程序數設定。
cat /proc/sys/kernel/pid_max
3880
測試 JUnit 4
thread
無窮迴圈建立執行緒,重複建立過程。
@Test
public void thread() {
for (;;) {
new Thread(() -> {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
}
}).start();
}
}
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:719)
at org.ruoxue.java_147.memory.UnableToCreateNewNativeThreadTest.thread(UnableToCreateNewNativeThreadTest.java:15)
UnableToCreateNewNativeThreadTest.java
package org.ruoxue.java_147.memory;
import org.junit.Test;
public class UnableToCreateNewNativeThreadTest {
@Test
public void thread() {
for (;;) {
new Thread(() -> {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
}
}).start();
}
}
}
修改設定
暫時修改,重啟機器後會失效。
ulimit -u 65535
永久修改。
vim /etc/security/limits.d/20-nproc.conf
* soft nproc 65535
* hard nproc 65535
暫時修改,重啟機器後會失效。
echo 65535 > /proc/sys/kernel/pid_max
永久修改。
vim /etc/sysctl.conf
kernel.pid_max = 65535
重載生效
sysctl -p
心得分享
- 考慮降低程式中建立執行緒的數量,分析系統應用是否真的需要建立這麼多執行緒。
- 如果真的需要建立大量執行緒,調整 OS 的線程最大數量。