Java多线程-线程池数量设置多少?JVM能跑多少线程?

==========================【导读】[开始]========================== 

        工作中实践到了多线程与高并发应用,也踩了一些沉重的坑。

万丈高楼起于垒土,学习与总结+工作实践不可相离。

本篇主题“JVM到底跑多少线程不会OOM?”“线程池设置多少线程合适?”

==========================【导读】[结束]========================== 

线程池设置多少线程合适?

    线程池过大,那么大量的线程将在相对很少的CPU和内存资源上发生竞争,这不仅会导致更高的内存使用量,而且还可能
耗尽资源。如果线程他过小,那么将导致许多空闲的处理器无法执行工作,从而降低吞吐率。
    设置线程池的大小,必须分析计算环境、资源预算和任务的特性。在部署的系统中有多少个CPU? 多大的内存? 任务是计
算密集型、I/O密集型还是二者皆可?
    计算密集型:在N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的利用率。(即使当计算密集型的线程偶
尔由于页缺失故障或者其他原因而暂停时,这个“额外”的线程也能确保CPU的时钟周期不会被浪费.)
    I/O密集型:N(thread) = N(cpu)*(1+w/c) 
    备注:W:I/O资源获取等待时间
    备注:C:除I/O资源获取外的计算时间

    当任务需要某种通过资源池来管理的资源时,例如数据库连接,那么线程池和资源池的大小将会相互影响.如果每个任务都
需要一个数据库连接,那么连接池的大小就限制了线程池的大小。同样,当线程池中的任务是数据库连接的唯一使用者时,那么
线程池的大小又将限制连接池的大小。
    还需要考虑容器运行环境配置:tomcat容器运行在jvm上,jvm运行在os上,jvm的线程和os的线程一一对应。

JVM到底跑多少线程不会OOM?

计算公式:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
MaxProcessMemory     指的是一个进程的最大内存
JVMMemory            JVM内存
ReservedOsMemory     保留的操作系统内存
ThreadStackSize      线程栈的大小
    Java中,当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,
而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。
    由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,
越容易发生java.lang.OutOfMemoryError: unable to create new native thread。
    如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过
修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:
    MaxProcessMemory  使用64位操作系统
    JVMMemory       减少JVMMemory的分配
    ThreadStackSize  减小单个线程的栈大小
示例:
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 



你可能感兴趣的:([JavaSE]_[线程并发])