JVM_OPT 线程限制

这里写链接内容

文章转载自《原文》
对于一个JVM实例到底能开多少个线程一直心存疑惑,所以打算实际测试下,简单google了把,找到影响线程数量的因素有下面几个:
-Xms
intial java heap size
-Xmx
maximum java heap size
-Xss
the stack size for each thread
系统限制
系统最大可开线程数

测试程序如下:
import java.util.concurrent.atomic.AtomicInteger;

public class TestThread extends Thread {
private static final AtomicInteger count = new AtomicInteger();

public static void main(String[] args) {  
    while (true)  
        (new TestThread()).start();  

}  

@Override  
public void run() {  
    System.out.println(count.incrementAndGet());  

    while (true)  
        try {  
            Thread.sleep(Integer.MAX_VALUE);  
        } catch (InterruptedException e) {  
            break;  
        }  
}  

}
测试环境:
系统:Ubuntu 10.04 Linux Kernel 2.6 (32位)
内存:2G
JDK:1.7
测试结果:
Ø 不考虑系统限制
-Xms
-Xmx
-Xss
结果
1024m
1024m
1024k
1737
1024m
1024m
64k
26077
512m
512m
64k
31842
256m
256m
64k
31842
在创建的线程数量达到31842个时,系统中无法创建任何线程。
由上面的测试结果可以看出增大堆内存(-Xms,-Xmx)会减少可创建的线程数量,增大线程栈内存(-Xss,32位系统中此参数值最小为60K)也会减少可创建的线程数量。
Ø 结合系统限制
线程数量31842的限制是是由系统可以生成的最大线程数量决定的:/proc/sys/kernel/threads-max,可其默认值是32080。修改其值为10000:echo 10000 > /proc/sys/kernel/threads-max,修改后的测试结果如下:
-Xms
-Xmx
-Xss
结果
256m
256m
64k
9761
这样的话,是不是意味着可以配置尽量多的线程?再做修改:echo 1000000 > /proc/sys/kernel/threads-max,修改后的测试结果如下:
-Xms
-Xmx
-Xss
结果
256m
256m
64k
32279
128m
128m
64k
32279
发现线程数量在达到32279以后,不再增长。查了一下,32位Linux系统可创建的最大pid数是32678,这个数值可以通过/proc/sys/kernel/pid_max来做修改(修改方法同threads-max),但是在32系统下这个值只能改小,无法更大。在threads-max一定的情况下,修改pid_max对应的测试结果如下:
pid_max
-Xms
-Xmx
-Xss
结果
1000
128m
128m
64k
582
10000
128m
128m
64k
9507
在Windows上的情况应该类似,不过相比Linux,Windows上可创建的线程数量可能更少。基于线程模型的服务器总要受限于这个线程数量的限制。
总结:
JVM中可以生成的最大数量由JVM的堆内存大小、Thread的Stack内存大小、系统最大可创建的线程数量(Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个方面影响。具体数量可以根据Java进程可以访问的最大内存(32位系统上一般2G)、堆内存、Thread的Stack内存来估算。
序:
在64位Linux系统(CentOS 6, 3G内存)下测试,发现还有一个参数是会限制线程数量:max user process(可通过ulimit –a查看,默认值1024,通过ulimit –u可以修改此值),这个值在上面的32位Ubuntu测试环境下并无限制。
将threads-max,pid_max,max user process,这三个参数值都修改成100000,-Xms,-Xmx尽量小(128m,64m),-Xss尽量小(64位下最小104k,可取值128k)。事先预测在这样的测试环境下,线程数量就只会受限于测试环境的内存大小(3G),可是实际的测试结果是线程数量在达到32K(32768,创建的数量最多的时候大概是33000左右)左右时JVM是抛出警告:Attempt to allocate stack guard pages failed,然后出现OutOfMemoryError无法创建本地线程。查看内存后发现还有很多空闲,所以应该不是内存容量的原因。Google此警告无果,暂时不知什么原因,有待进一步研究。
序2:
今天无意中发现文章[7],马上试了下,果然这个因素会影响线程创建数量,按文中描述把/proc/sys/vm/max_map_count的数量翻倍,从65536变为131072,创建的线程总数量达到65000+,电脑基本要卡死(3G内存)… 简单查了下这个参数的作用,在[8]中的描述如下:
“This file contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries.
While most applications need less than a thousand maps, certain programs, particularly malloc debuggers, may consume lots of them, e.g., up to one or two maps per allocation.
The default value is 65536.”
OK,这个问题总算完满解决,最后总结下影响Java线程数量的因素:
Java虚拟机本身:-Xms,-Xmx,-Xss;
系统限制:
/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process(ulimit -u),
/proc/sys/vm/max_map_count。

这里写链接内容

centos 7.x设置守护进程的文件数量限制
转载 2016年06月24日 17:37:14 36

02

在Bash中有个ulimit命令,提供了对Shell及该Shell启动的进程的可用资源控制。主要包括打开文件描述符数量、用户的最大进程数量、coredump文件的大小等。

在CentOS 5/6等版本中,资源限制的配置可以在/etc/security/limits.conf设置,针对root/user等各个用户或者*代表所有用户来设置。
当然,/etc/security/limits.d/
中可以配置,系统是先加载limits.conf然后按照英文字母顺序加载limits.d目录下的配置文件,后加载配置覆盖之前的配置。 一个配置示例如下:

  • soft nofile 100000
  • hard nofile 100000
  • soft nproc 100000
  • hard nproc 100000
  • soft core 100000
  • hard core 100000

不过,在CentOS 7/RHEL 7的系统中,使用Systemd替代了之前的SysV,因此/etc/security/limits.conf
文件的配置作用域缩小了一些。limits.conf这里的配置,只适用于通过PAM认证登录用户的资源限制,它对systemd的service的资源限制不生效。登录用户的限制,与上面讲的一样,通过/etc/security/limits.conf和
limits.d来配置即可。

对于systemd service的资源限制,如何配置呢?

全局的配置,放在文件/etc/systemd/system.conf和/etc/systemd/user.conf。
同时,也会加载两个对应的目录中的所有.conf文件/etc/systemd/system.conf.d/.conf和/etc/systemd/user.conf.d/.conf

其中,system.conf是系统实例使用的,user.conf用户实例使用的。一般的sevice,使用system.conf中的配置即可。systemd.conf.d/*.conf中配置会覆盖system.conf。

DefaultLimitCORE=infinity
DefaultLimitNOFILE=100000
DefaultLimitNPROC=100000

注意:修改了system.conf后,需要重启系统才会生效。

针对单个Service,也可以设置,以nginx为例。

编辑/usr/lib/systemd/system/nginx.service文件,或者/usr/lib/systemd/system/nginx.service.d/my-limit.conf文件,做如下配置:

[Service]
LimitCORE=infinity
LimitNOFILE=100000
LimitNPROC=100000

然后运行如下命令,才能生效。

sudo systemctl daemon-reload
sudo systemctl restart nginx.service

查看一个进程的limit设置:cat /proc/YOUR-PID/limits

例如我的一个nginx service的配置效果:

cat/proc/ (cat /var/run/nginx.pid)/limits

Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 100000 100000 processes
Max open files 100000 100000 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 1030606 1030606 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us

顺便提一下,CentOS7自带的/etc/security/limits.d/20-nproc.conf,里面默认设置了非root用户的最大进程数为4096,被limit.d目录中的配置覆盖了。

参考文档:

man systemd

man systemd-system.conf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值