我无法在具有15G内存的Linux机器上创建超过32k的Java线程。
答案 0 :(得分:37)
您可以使用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.
错误消息,并调用os :: guard_memory()。在Linux中,此函数是mprotect()。
echo 1999999 > /proc/sys/vm/max_map_count
或
sys.vm.max_map_count = 1999999
/etc/sysctl.conf
永久更改。
答案 1 :(得分:7)
现代(systemd)linux系统的附加信息。
关于这些可能需要调整的值的资源很多(另一个答案是大多数的好的来源);但是,通过系统化的“TasksMax”限制,在cgroup上设置pids.max,会产生新的限制。
对于登录会话,UserTasksMax默认值是内核限制pids_max的33%(通常为12,288),可以在/etc/systemd/logind.conf中覆盖。
对于服务,DefaultTasksMax默认值是内核限制pids_max的15%(通常为4,915)。您可以通过在“systemctl edit”中设置TasksMax或在/etc/systemd/system.conf中更新DefaultTasksMax来覆盖服务
答案 2 :(得分:1)
我在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
我还必须将DefaultTasksMax
中的/etc/systemd/system.conf
(或/etc/systemd/user.conf
用于用户运行的服务)设置为DefaultTasksMax=unlimited
。
Systemd还对从登录Shell运行的程序施加了限制。 这些默认值是每位用户4096(将增加到12288),并且 在[登录]部分中配置为UserTasksMax
/etc/systemd/logind.conf
。
那是来自this StackExchange question的。将我的UserTasksMax
设置为UserTasksMax=999999
对我有用。