如何增加JVM线程的最大数量(Linux 64位)

时间:2015-12-24 11:45:06

标签: java linux multithreading jvm

我无法在具有15G内存的Linux机器上创建超过32k的Java线程。

3 个答案:

答案 0 :(得分:37)

您可以使用sample program查找当前的线程限制。

如果遇到Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread,请查看以下内容:

  1. 在小型内存机中

    每个Java线程都使用自己的堆栈内存。默认堆栈大小为1024k(= 1M)。您可以像java -Xss512k ...那样减小堆栈大小。如果堆栈大小太小,则无法启动JVM。

    并注意堆内存配置:(初始)-Xms和(最大)-Xmx。分配给堆的内存越多,堆栈的可用内存就越少。

  2. 系统限制

    ulimit -a中的某些值会影响线程限制。

    • max memory size - 大多数64位计算机无限制
    • max user processes - linux处理类似进程的线程
    • virtual memory - 在大多数64位计算机上无限制。虚拟内存使用量增加-Xss配置(默认1024k)

    您可以通过(暂时)运行ulimit命令或(永久)修改/etc/security/limits.conf来更改这些值。

  3. 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永久更改。

  4. 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

  5. sys.vm.max_map_count

    cat /proc/sys/vm/max_map_count至少应为(2 x线程数)。

    JavaThread :: create_stack_guard_pages()发出

    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对我有用。