如何增加最大 JVM 线程数(Linux 64 位)
How to increase maximum number of JVM threads (Linux 64bit)
我无法在具有 15G 内存的 Linux 机器上创建超过 32k Java 个线程。
您可以使用 sample program 找出当前的线程限制。
如果遇到Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
,检查这些:
在小内存机器中
每个 Java 线程都使用自己的堆栈内存。默认堆栈大小为 1024k (= 1M)。您可以像 java -Xss512k ...
一样减少堆栈大小。如果堆栈大小太低,则无法启动 JVM。
注意堆内存配置:(初始)-Xms
和(最大)-Xmx
。分配给堆的内存越多,栈的可用内存就越少。
系统限制
ulimit -a
中的某些值会影响线程限制。
max memory size
- 在大多数 64 位机器上无限制
max user processes
- linux 将线程视为进程
virtual memory
- 在大多数 64 位机器上没有限制。 -Xss 配置增加虚拟内存使用量(默认 1024k)
您可以通过(临时)运行 ulimit
命令或(永久)编辑 /etc/security/limits.conf
.
更改这些值
sys.kernel.threads-max
这个值是系统全局(包括非JVM进程)的最大线程数。勾选 cat /proc/sys/kernel/threads-max
,必要时增加。
echo 999999 > /proc/sys/kernel/threads-max
或
sys.kernel.threads-max = 999999
在 /etc/sysctl.conf
中永久更改。
sys.kernel.pid_max
如果cat /proc/sys/kernel/pid_max
与当前限制相似,请增加此值。 Linux 将线程视为进程。
echo 999999 > /proc/sys/kernel/pid_max
或
sys.kernel.pid_max = 999999
在 /etc/sysctl.conf
中永久更改。
您可能还需要增加 sys.vm.max_map_count
。
sys.vm.max_map_count
cat /proc/sys/vm/max_map_count
应该至少是(2 x 线程数)。
Attempt to protect stack guard pages failed.
和 OpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
错误消息由 JavaThread::create_stack_guard_pages() 发出,它调用 os::guard_memory()。在Linux中,这个函数是mprotect()。
echo 1999999 > /proc/sys/vm/max_map_count
或
sys.vm.max_map_count = 1999999
在 /etc/sysctl.conf
中永久更改。
现代 (systemd) linux 系统的附加信息。
有许多关于此值的资源可能需要调整(另一个答案对大多数资源来说都是很好的来源);然而,通过 systemd "TasksMax" 限制对 cgroup 设置 pids.max 施加了新的限制。
对于登录会话,UserTasksMax 默认值为内核限制 pids_max(通常为 12,288)的 33%,可以在 /etc/systemd/logind.conf.
中覆盖
对于服务,DefaultTasksMax 默认值是内核限制 pids_max 的 15%(通常为 4,915)。您可以通过在 "systemctl edit" 中设置 TasksMax 或在 /etc/systemd/system.conf
中更新 DefaultTasksMax 来为服务覆盖它
我 运行 在 Python 程序中遇到了类似的问题,以下对我有用。这是基于上面 maczniak 的回答和 https://superuser.com/questions/1219960/cannot-edit-proc-sys-kernel-threads-max.
echo kernel.threads-max = 1073741823 >> /etc/sysctl.conf && echo 1073741823 > /proc/sys/kernel/threads-max
echo kernel.pid_max = 999999 >> /etc/sysctl.conf && echo 999999 > /proc/sys/kernel/pid_max
echo vm.max_map_count = 2147483646 >> /etc/sysctl.conf && echo 2147483646 > /proc/sys/vm/max_map_count
echo vm.overcommit_memory = 1 >> /etc/sysctl.conf && echo 1 > /proc/sys/vm/overcommit_memory
echo fs.inotify.max_user_instances = 256 >> /etc/sysctl.conf && echo 256 > /proc/sys/fs/inotify/max_user_instances
sysctl -p
我还必须将 /etc/systemd/system.conf
中的 DefaultTasksMax
(或 user-run 服务的 /etc/systemd/user.conf
)设置为 DefaultTasksMax=unlimited
。
Systemd also applies a limit for programs run from a login-shell.
These default to 4096 per user (will be increased to 12288) and are
configured as UserTasksMax in the [Login] section of
/etc/systemd/logind.conf
.
来自this StackExchange question。将我的 UserTasksMax
设置为 UserTasksMax=999999
对我有用。
我无法在具有 15G 内存的 Linux 机器上创建超过 32k Java 个线程。
您可以使用 sample program 找出当前的线程限制。
如果遇到Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
,检查这些:
在小内存机器中
每个 Java 线程都使用自己的堆栈内存。默认堆栈大小为 1024k (= 1M)。您可以像
java -Xss512k ...
一样减少堆栈大小。如果堆栈大小太低,则无法启动 JVM。注意堆内存配置:(初始)
-Xms
和(最大)-Xmx
。分配给堆的内存越多,栈的可用内存就越少。系统限制
ulimit -a
中的某些值会影响线程限制。max memory size
- 在大多数 64 位机器上无限制max user processes
- linux 将线程视为进程virtual memory
- 在大多数 64 位机器上没有限制。 -Xss 配置增加虚拟内存使用量(默认 1024k)
您可以通过(临时)运行
ulimit
命令或(永久)编辑/etc/security/limits.conf
. 更改这些值
sys.kernel.threads-max
这个值是系统全局(包括非JVM进程)的最大线程数。勾选
cat /proc/sys/kernel/threads-max
,必要时增加。echo 999999 > /proc/sys/kernel/threads-max
或
sys.kernel.threads-max = 999999
在/etc/sysctl.conf
中永久更改。sys.kernel.pid_max
如果
cat /proc/sys/kernel/pid_max
与当前限制相似,请增加此值。 Linux 将线程视为进程。echo 999999 > /proc/sys/kernel/pid_max
或
sys.kernel.pid_max = 999999
在/etc/sysctl.conf
中永久更改。您可能还需要增加
sys.vm.max_map_count
。sys.vm.max_map_count
cat /proc/sys/vm/max_map_count
应该至少是(2 x 线程数)。Attempt to protect stack guard pages failed.
和OpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
错误消息由 JavaThread::create_stack_guard_pages() 发出,它调用 os::guard_memory()。在Linux中,这个函数是mprotect()。echo 1999999 > /proc/sys/vm/max_map_count
或
sys.vm.max_map_count = 1999999
在/etc/sysctl.conf
中永久更改。
现代 (systemd) linux 系统的附加信息。
有许多关于此值的资源可能需要调整(另一个答案对大多数资源来说都是很好的来源);然而,通过 systemd "TasksMax" 限制对 cgroup 设置 pids.max 施加了新的限制。
对于登录会话,UserTasksMax 默认值为内核限制 pids_max(通常为 12,288)的 33%,可以在 /etc/systemd/logind.conf.
中覆盖对于服务,DefaultTasksMax 默认值是内核限制 pids_max 的 15%(通常为 4,915)。您可以通过在 "systemctl edit" 中设置 TasksMax 或在 /etc/systemd/system.conf
中更新 DefaultTasksMax 来为服务覆盖它我 运行 在 Python 程序中遇到了类似的问题,以下对我有用。这是基于上面 maczniak 的回答和 https://superuser.com/questions/1219960/cannot-edit-proc-sys-kernel-threads-max.
echo kernel.threads-max = 1073741823 >> /etc/sysctl.conf && echo 1073741823 > /proc/sys/kernel/threads-max
echo kernel.pid_max = 999999 >> /etc/sysctl.conf && echo 999999 > /proc/sys/kernel/pid_max
echo vm.max_map_count = 2147483646 >> /etc/sysctl.conf && echo 2147483646 > /proc/sys/vm/max_map_count
echo vm.overcommit_memory = 1 >> /etc/sysctl.conf && echo 1 > /proc/sys/vm/overcommit_memory
echo fs.inotify.max_user_instances = 256 >> /etc/sysctl.conf && echo 256 > /proc/sys/fs/inotify/max_user_instances
sysctl -p
我还必须将 /etc/systemd/system.conf
中的 DefaultTasksMax
(或 user-run 服务的 /etc/systemd/user.conf
)设置为 DefaultTasksMax=unlimited
。
Systemd also applies a limit for programs run from a login-shell. These default to 4096 per user (will be increased to 12288) and are configured as UserTasksMax in the [Login] section of
/etc/systemd/logind.conf
.
来自this StackExchange question。将我的 UserTasksMax
设置为 UserTasksMax=999999
对我有用。