JVM中可生成的最大Thread数量

最近想测试下Openfire下的最大并发数,需要开大量线程来模拟客户端。对于一个JVM实例到底能开多少个线程一直心存疑惑,所以打算实际测试下,简单google了把,找到影响线程数量的因素有下面几个:

-Xms

intial java heap size

-Xmx

maximum java heap size

-Xss

the stack size for each thread

系统限制

系统最大可开线程数

测试程序如下:
  1. import java.util.concurrent.atomic.AtomicInteger; 
  2. public class TestThread extends Thread { 
  3.     private static final AtomicInteger count = new AtomicInteger(); 
  4.     public static void main(String[] args) { 
  5.         while (true) 
  6.             (new TestThread()).start(); 
  7.     } 
  8.     @Override 
  9.     public void run() { 
  10.         System.out.println(count.incrementAndGet()); 
  11.         while (true) 
  12.             try { 
  13.                 Thread.sleep(Integer.MAX_VALUE); 
  14.             } catch (InterruptedException e) { 
  15.                 break; 
  16.             } 
  17.     } 

测试环境:

系统: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。

参考资料:

1. http://blog.krecan.net/2010/04/07/how-many-threads-a-jvm-can-handle/

2. http://www.cyberciti.biz/tips/maximum-number-of-processes-linux-26-kernel-can-handle.html

3. http://geekomatic.ch/2010/11/24/1290630420000.html

4. http://stackoverflow.com/questions/763579/how-many-threads-can-a-java-vm-support

5. http://www.iteye.com/topic/1035818

6. http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html

7. https://listman.redhat.com/archives/phil-list/2003-August/msg00025.html

8. http://www.linuxinsight.com/proc_sys_vm_max_map_count.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Abp.Zero 搭建第三方登录模块(一):原理篇

🚀 优质资源分享 🚀 学习路线指引(点击解锁)知识定位人群定位🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一…

手游server之数据IO进化

这里数据IO是指游戏数据存盘和读取。假设IO处理不好。server在IO时会导致。游戏卡顿较长的时间,严重影响游戏体验。近期服务端刚好对IO这一块做了优化,把优化过程记录一下。一 原始版 刚開始立项的时候,仅仅是做了一个Demo,加上也…

MSP430F5529 DriverLib 库函数学习笔记(十二)I2C实战

目录上机实战I2C给 DAC 芯片 DAC7571 写入数字量DAC7571 介绍程序分析引脚复用I2C 初始化发送一个字节发送一个字读取一个字节读取多个字节中断服务函数整体代码main.cMSP430F5529_I2C.cMSP430F5529_I2C.h实验结果I2C 读取 TMP421 温度TMP421 简介程序摘要TMP421初始化温度的读…

mysqldump造成Buffer Pool污染的研究 [转]

原文链接:http://www.shaoqun.com/m/a/43307.aspx 前言: 最近Oracle MySQL在其官方Blog上贴出了 5.6中一些变量默认值的修改。其中innodb_old_blocks_time 的默认值从0替换成了1000(即1s) 关于该参数的作用摘录如下: h…

自动加载缓存框架

2019独角兽企业重金招聘Python工程师标准>>> 自动加载缓存框架 代码,请访问github 获取更详情,更新的内容 QQ交流群:429274886,版本更新会在群里通知,能了解最新动态 0.5版本已经是稳定版本了,大家可以放心…

(数据科学学习手札139)geopandas 0.11版本重要新特性一览

🚀 优质资源分享 🚀 学习路线指引(点击解锁)知识定位人群定位🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一…

MSP430F5529 DriverLib 库函数学习笔记(十三)认识低功耗模式

目录硬知识低功耗模式MSP430单片机各工作模式下的电流消耗API进入低功耗模式退出低功耗模式平台:Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 硬知识 低功耗模式 MSP430单片机具有7种低功耗模式(LPM0…

剖析虚幻渲染体系(16)- 图形驱动的秘密

🚀 优质资源分享 🚀 学习路线指引(点击解锁)知识定位人群定位🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一…

方法性能分析器--装饰者模式应用

<!DOCTYPE html> <html> <head><title>方法性能分析器</title><meta charset"utf-8"> </head> <body> <div id"list-container"></div><script>function $(id){return document.getEle…

Python NLPIR(中科院汉语分词系统)的使用 十五分钟快速入门与完全掌握

前叙 博主写这篇文章使用了八十分钟,阅读需要十五分钟,读完之后你将会学会在Python中使用NLPIR2016.如果你花费更多的时间练习后半部分的例子,你将能够在一天内学会在Python中使用NLPIR2016的全部所需知识 如果你想要获取更详细的API翻译,你需要进一步学习ctypes,附赠一篇关于…

微信朋友圈也可以发语音你们造吗?

在微信朋友圈发照片太矫情&#xff0c;小视频又耗流量&#xff0c;只发文字又太单调&#xff0c;何不发段语音来呼朋唤友呢&#xff1f;你是说朋友圈发语音&#xff1f;这是真的吗&#xff1f;sure&#xff0c;开发者已经利用微信JS-SDK接口实现了&#xff0c;扫描下方的二维码…

MSP430F5529 DriverLib 库函数学习笔记(十四)看门狗定时器 (WDT)

目录硬知识看门狗定时计数器 &#xff08;WDTCNT&#xff09;看门狗模式定时计数模式看门狗定时器中断时钟故障保护功能低功耗模式下的看门狗操作看门狗定时器控制寄存器WDT_A API (机翻)参数上机实战定时计数模式配置中断服务函数整体代码实验结果看门狗模式配置整体代码平台&…

初学 Unsupervised feature learning and deep learning--Sparse autoencoder

今天做了一下 Stanford CS294A 的一个 programming assignment: sparse autoencoder 因为之前做过 Andrew Ng 的 ml online class 的 neural network 那节的作业&#xff0c;所以这个实现起来就很 easy 了。直接贴代码&#xff08;all vectorized&#xff09;&#xff1a;1 [d …

【Nginx】Windows平台下配置Nginx服务实现负载均衡

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

PLC基础入门

PLC编程入门基础技术知识学习 2016-06-27 xjp7879 摘自 电工技术知...第一章 可编程控制器简介 可编程序控制器&#xff0c;英文称Programmable Controller&#xff0c;简称PC。但由于PC容易和个人计算机&#xff08;Personal Computer&#xff09;混淆&#xff0c;故人们仍习…

MSP430F5529 DriverLib 库函数学习笔记(十五)SFR 模块

目录API (机翻)SFR管理中断的函数SFR 管理RST/NMI引脚控制的函数参数平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) API (机翻) 特殊函数寄存器API提供了一组用于使用MSP430Ware SFR模块的函数。提供了启用和禁…

View,SurfaceView,SurfaceHolder

View&#xff1a;对于绘画来说&#xff0c;最重要的步骤是重载 onDraw方法并且修改画布Canvas。 SurfaceView&#xff1a;1&#xff0c;You can control the format of this surface and, if you like, its size; 2&#xff0c;One of the purposes of this class is to provid…

Xcode 的正确打开方式——Debugging

2019独角兽企业重金招聘Python工程师标准>>> 程序员日常开发中有大量时间都会花费在 debug 上&#xff0c;从事 iOS 开发不可避免地需要使用 Xcode。这篇博客就主要介绍了 Xcode 中几种能够大幅提升代码调试效率的方式。 “If debugging is the process of removing…

VS Code 调试 PHP有关配置

一、安装VS CODE 、 WampServer 二、用VS Code 打开php项目后&#xff0c;提示 "Cannot validate since no PHP executable is set. Use the setting php.validate.executablePath to configure the PHP executable." 解决方法如下&#xff1a; 在“文件”-“首选项”…

MSP430F5529 DriverLib 库函数学习笔记(十六)比较器B Comp_B

目录硬知识比较器B介绍比较器 B 的特点比较器 B 的结构模拟输入部分比较部分基准电压部分低通滤波部分比较器和普通运放的区别比较器B测量电阻原理利用比较器B实现电容触摸按键原理比较器B控制寄存器COMP_B API (机翻)介绍处理初始化和输出的函数参数处理中断的函数参数处理COM…