jvm最大线程数
摘自:http://sesame.iteye.com/blog/622670
工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题、分析问题、解决问题。
一、认识问题:
首先我们通过下面这个 测试程序 来认识这个问题:
运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK
1.6.0_18, eclipse 3.4,
测试程序:
- import java.util.concurrent.CountDownLatch;
- public class TestNativeOutOfMemoryError {
- public static void main(String[] args) {
- for (int i = ;; i++) {
- System.out.println("i = " + i);
- new Thread(new HoldThread()).start();
- }
- }
- }
- class HoldThread extends Thread {
- CountDownLatch cdl = new CountDownLatch();
- public HoldThread() {
- this.setDaemon(true);
- }
- public void run() {
- try {
- cdl.await();
- } catch (InterruptedException e) {
- }
- }
- }
import java.util.concurrent.CountDownLatch; public class TestNativeOutOfMemoryError { public static void main(String[] args) { for (int i = 0;; i++) { System.out.println("i = " + i); new Thread(new HoldThread()).start(); } } } class HoldThread extends Thread { CountDownLatch cdl = new CountDownLatch(1); public HoldThread() { this.setDaemon(true); } public void run() { try { cdl.await(); } catch (InterruptedException e) { } } }
不指定任何JVM参数,eclipse中直接运行输出,看到了这位朋友了吧:
i = 5602
Exception in thread "main" java.lang.OutOfMemoryError:
unable to create new native thread
at
java.lang.Thread.start0(Native Method)
at
java.lang.Thread.start(Thread.java:597)
at
TestNativeOutOfMemoryError.main(TestNativeOutOfMemoryError.java:20)
二、分析问题:
这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。能创建的线程数的具体计算公式如下:
(MaxProcessMemory - JVMMemory -
ReservedOsMemory) / (ThreadStackSize) = Number of
threads
MaxProcessMemory
指的是一个进程的最大内存
JVMMemory
JVM内存
ReservedOsMemory
保留的操作系统内存
ThreadStackSize 线程栈的大小
在java语言里,当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory
- JVMMemory - ReservedOsMemory)。
结合上面例子我们来对公式说明一下:
MaxProcessMemory 在32位的 windows下是
2G
JVMMemory eclipse默认启动的程序内存是64M
ReservedOsMemory
一般是130M左右
ThreadStackSize 32位 JDK 1.6默认的stacksize
325K左右
公式如下:
(2*1024*1024-64*1024-130*1024)/325 =
5841
公式计算所得5841,和实践5602基本一致(有偏差是因为ReservedOsMemory不能很精确)
由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生java.lang.OutOfMemoryError:
unable to create new native thread。
咦,有点背我们的常理,恩,让我们来验证一下,依旧使用上面的测试程序,加上下面的JVM参数,测试结果如下:
ThreadStackSize
JVMMemory
能创建的线程数
默认的325K
-Xms1024m -Xmx1024m i =
2655
默认的325K
-Xms1224m -Xmx1224m i =
2072
默认的325K
-Xms1324m -Xmx1324m i =
1753
默认的325K
-Xms1424m -Xmx1424m i =
1435
-Xss1024k
-Xms1424m -Xmx1424m i = 452
完全和公式一致。
三、解决问题:
1,如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。
2,如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:
a,
MaxProcessMemory 使用64位操作系统
b, JVMMemory 减少JVMMemory的分配
c,
ThreadStackSize 减小单个线程的栈大小
四、其他:
在java应用中,有时候会出现这样的错误:OutOfMemoryError: unable
to create new native
thread.这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。
每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。
这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。
给出一个有关能够创建线程的最大个数的估算公式:
(MaxProcessMemory
- JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of
threads
对于jdk1.5而言,假设操作系统保留120M内存:
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB)
= ~380 threads
1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880
threads
对于栈大小为256KB的jdk1.4而言,
1.5GB allocated to JVM: ~1520
threads
1.0GB allocated to JVM: ~3520 threads
jvm最大线程数的更多相关文章
- Jvm支持的最大线程数
摘自 http://blog.csdn.net/xyls12345/article/details/26482387 JVM最大线程数 (2012-07-04 23:20:15) 转载▼ 标签: jv ...
- JVM可支持的最大线程数(转)
摘自:http://sesame.iteye.com/blog/622670 工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题. ...
- JVM可支持的最大线程数
转微博,因为他也是转载 不知道原出处 一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun J ...
- 180724-统计JVM进程中线程数两种方式小记
I. 统计进程中的线程数 相关系列博文推荐: 180711-JVM定位分析CPU性能消耗 180704-JDK常用监控参数 jvm调优的工具介绍 1. proc查询 /proc 目录以可读文本文件形式 ...
- 聊下并发和Tomcat线程数(错误更正)
本文前半部分结论存在严重错误,请看最后2015-1-20更新部分. 最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池 ...
- 聊下并发和Tomcat线程数(Updated)
最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s. 服务器性能很好,Tomcat版本是 ...
- Java调优之jvm和线程的内存分析
本文来源于铁木箱子的博客http://www.mzone.cc 这几天因为自己开发的一个网站在768M内存的机器上撑不起100多个用户的运行,因为每个用户启用功能后,系统将为每个用户分配8个左右的独立 ...
- Tomcat设置最佳线程数总结
最佳线程数: 性能压测的情况下,起初随着用户数的增加,QPS会上升,当到了一定的阀值之后,用户数量增加QPS并不会增加,或者增加不明显,同时请求的响应时间却大幅增加.这个阀值我们认为是最佳线程数. 为 ...
- 浅谈并发和tomcat线程数
假设Tomcat每到固定一个时间会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s. 服务器性能很好,Tomcat版本是7.0.54,配置如下 & ...
随机推荐
- ps如果换背景
一.魔棒工具 魔棒工具主要是使用户可以选择颜色一致的区域(例如,一朵红花)或者背景比较单调的图片,而不必跟踪其轮廓.魔棒工具选择的颜色范围可以由工具选项栏中的误差范围 参数值来控制. 二.钢笔工具 路 ...
- webpack基础使用
环境: win10, webpack v3.5.6, node v8.4, npm v5.3. 安装与配置 新建一个项目目录demo, 在当前目录执行如下命令: npm init -y npm ins ...
- Differences between Python2 and Python3
@1:str, repr和反引号是Python将值转为字符串的3种方法repr创建一个字符串,它以合法的Python表达式的形式表示该字符串.Python2还有反引号`,但Python3中没有反引号, ...
- python s12
logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式 ...
- django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统
Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...
- window.event.keycode值大全
window.event.keycode值大全 event.keycode值大全 1 keycode 8 = BackSpace BackSpace 2 keycode 9 = Tab Tab 3 k ...
- linux centos7 安装zookeeper
linux 系统下 zookeeper 安装教程 1.下载安装包 1)进入安装目录 cd /home/install/ 2)下载 wget http://mirror.bit.edu.cn/apach ...
- 08/27 Django admin相关
一.django-admin的简单回顾: admin: Django的后台数据管理的web版本 1.admin a:models.py - 创建表 b:admin.py - 注册表 admin. ...
- shell脚本实现进度条
使用shell脚本编写进度条 可已加入到shell脚本当中 主要作用:好看 美观 没毛用 (一) 普通进度条: #!/bin/bashb='' for ((i=0;$i<=20;i++)) do ...
- Mac开发
工具类:
