当前位置:必发365电子游戏 > 编程 > 能够把命令加到profile文件里,而贰个经过中可用的内部存款和储蓄器空间唯有2G
能够把命令加到profile文件里,而贰个经过中可用的内部存款和储蓄器空间唯有2G
2019-12-19

查看最大线程数:

单个进度中最大线程数探求,进度线程探寻

【转载自

windows 操作系统中允许的最大线程数。

 

===========================================================================

默许景况下,多个线程的栈要预先流出1M的内部存款和储蓄器空间

而二个进度中可用的内部存款和储蓄器空间唯有2G,所以理论上一个经过中最多能够开20四十八个线程

可是内部存款和储蓄器当然不容许完全拿来作线程的栈,所以其实数目要比那些值要小。

你也得以由此三回九转时改善暗许栈大小,将其改的非常的小,那样就能够多开部分线程。

如将私下认可栈的分寸改成512K,那样辩驳上最多就足以开40九十七个线程。

必发365电子游戏,固然物理内部存款和储蓄器再大,一个进度中能够起的线程总要受到2GB这么些内部存款和储蓄器空间的界定。

比方说你的机械装了64GB物理内部存款和储蓄器,但各种进程的内部存款和储蓄器空间依然4GB,在那之中客商态可用的要么2GB。

倘要是相近台机械内的话,能起些许线程也是受内部存储器限定的。每一种线程对象都要站用非页面内部存款和储蓄器,而

非页面内部存款和储蓄器也许有限的,当非页面内存被耗尽时,也就不能够创立线程了。

意气风发经物理内部存款和储蓄器相当的大,同生机勃勃台机械内足以跑的线程数目标界定值会更大。

在Windows下写个程序,二个历程Fork出2003个左右线程就能够要命退出了,为何?

本条难点的发出是因为windows三十一位系统,三个过程所能使用的最大设想内部存款和储蓄器为2G,而贰个线程的

暗中同意线程栈StackSize为1024K(1M),那样当线程数量围拢二〇〇三时,二〇〇四*1024K=2G(大约),

内部存款和储蓄器能源就一定于耗尽。

MSDN原文:

“The number of threads a process can create is limited by the available virtual memory.

 By default, every thread has one megabyte of stack space. Therefore, you can create

 at most 2,028 threads. If you reduce the default stack size, you can create more threads. However, your application will have better performance if you create one thread per

processor and build queues of requests for which the application maintains the context

information. A thread would process all requests in a queue before processing requests

in the next queue.”

 

何以突破二零零四个限定?

能够通过更改CreateThread参数来压缩线程栈StackSize,例如

 

view plaincopy to clipboard  

  1. #define MAX_THREADS 50000   
  2.     DWORD WINAPI ThreadProc( LPVOID lpParam ){  
  3.         while(1){  
  4.             Sleep(100000);  
  5.         }  
  6.         return 0;  
  7.     }  
  8.     int main() {  
  9.         DWORD dwThreadId[MAX_THREADS];  
  10.         HANDLE hThread[MAX_THREADS];  
  11.         for(int i = 0; i < MAX_THREADS; ++i){  
  12.         hThread[i] = CreateThread(0, 64, ThreadProc, 0, STACK_SIZE_PARAM_IS_A_RESERVATION, &dwThreadId[i]);  
  13.             if(0 == hThread[i]){  
  14.                 DWORD e = GetLastError();  
  15.                 printf(“%drn”,e);  
  16.                 break;  
  17.             }  
  18.         }  
  19.      ThreadProc(0);  
  20.    }  

 

Cpp代码 

  1. #define MAX_THREADS 50000  
  2.     DWORD WINAPI ThreadProc( LPVOID lpParam ){  
  3.         while(1){  
  4.             Sleep(100000);  
  5.         }  
  6.         return 0;  
  7.     }  
  8.     int main() {  
  9.         DWORD dwThreadId[MAX_THREADS];  
  10.         HANDLE hThread[MAX_THREADS];  
  11.         for(int i = 0; i < MAX_THREADS; ++i){  
  12.         hThread[i] = CreateThread(0, 64, ThreadProc, 0, STACK_SIZE_PARAM_IS_A_RESERVATION, &dwThreadId[i]);  
  13.             if(0 == hThread[i]){  
  14.                 DWORD e = GetLastError();  
  15.                 printf(“%drn”,e);  
  16.                 break;  
  17.             }  
  18.         }  
  19.      ThreadProc(0);  
  20.    }  

 

 

 

劳动器端程序设计

假若你的劳动器端程序设计成:来二个client连接诉求则开创五个线程,那么就能够存在二零零二个限定(在

硬件内部存储器和CPU个数一定的事态下)。提议如下:

The “one thread per client” model is well-known not to scale beyond a dozen clients

or so. If you‘re going to be handling more than that many clients simultaneously,

you should move to a model where instead of dedicating a thread to a client, you

 instead allocate an object. (Someday I’ll muse on the duality between threads and

 objects.) Windows provides I/O completion ports and a thread pool to help you

convert from a thread-based model to a work-item-based model.

  1. Serve many clients with each thread, and use nonblocking I/O and level-triggered

readiness notification

  1. Serve many clients with each thread, and use nonblocking I/O and readiness

change notification

  1. Serve many clients with each server thread, and use asynchronous I/O

附:Win32将低区的2GB留给进度使用, 高区的2GB则留给系统应用。

Linux将高位1GB留给内核,低位3GB留给进度

 

linux系统中允许的最大线程数

==========================================================================================

cat /proc/sys/kernel/threads-max

JVM中可生成的最大Thread数量

 

JVM中能够变动的最大数据由JVM的堆内部存款和储蓄器大小、Thread的Stack内部存款和储蓄器大小、系统最大

可创设的线程数量(Java线程的完毕是依照底层系统的线程机制来落到实处的,Windows下_beginthreadex,Linux下pthread_create)多少个地点影响。

  近期想测量检验下Openfire下的最大并发数,需求开大气线程来效仿顾客端。对于叁个JVM实例到底能开多少个线程平昔心存嫌疑,所以计划实际测量检验下,简单google了把,找到影响线程数量的成分有上面多少个:

-Xms

intial Java heap size

-Xmx

maximum java heap size

-Xss

the stack size for each thread

系统限制

系统最大可开线程数

测量试验程序如下:   view plaincopy to clipboard  

  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.     }   
  18. }   

Java代码 

  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.     }   
  18. }   

 

测验意况:

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

在开创的线程数量达到31844个时,系统中不可能创设任何线程。

 

由地点的测量试验结果能够见到增大堆内部存款和储蓄器(-Xms,-Xmx)会压缩可创建的线程数量,增大线程栈内部存款和储蓄器

(-Xss,叁拾一个人系统中此参数值最小为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现在,不再进步。查了生龙活虎晃,三14位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进度能够访谈的最大内部存储器(三十个人系统上相通2G)、

堆内部存款和储蓄器、Thread的Stack内存来猜度。

序:

 

      在61个人Linux系统(CentOS 6, 3G内部存款和储蓄器)下测量检验,开掘还只怕有二个参数是会限定线程数量:

max user process(可由此ulimit –a查看,私下认可值1024,通过ulimit –u能够修正此值),

本条值在下边包车型客车叁九位Ubuntu测量试验意况下并无界定。

将threads-max,pid_max,max user process,那四个参数值都改过成100000,-Xms,

-Xmx尽量小(128m,64m),-Xss尽量小(陆拾个人下纤维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。

【转载自 windows操作系统中允许的最大线程数。 ====...

ulimit

User limits - limit the use of system-wide resources.

Syntax
ulimit [-acdfHlmnpsStuv] [limit]

Options

-S Change and report the soft limit associated with a resource. 
-H Change and report the hard limit associated with a resource. 

-a All current limits are reported. 
-c The maximum size of core files created. 
-d The maximum size of a process's data segment. 
-f The maximum size of files created by the shell(default option) 
-l The maximum size that may be locked into memory. 
-m The maximum resident set size. 
-n The maximum number of open file descriptors. 
-p The pipe buffer size. 
-s The maximum stack size. 
-t The maximum amount of cpu time in seconds. 
-u The maximum number of processes available to a single user. 
-v The maximum amount of virtual memory available to the process. 

ulimit provides control over the resources available to the shell and to processes started by it, on systems that allow such control.

If limit is given, it is the new value of the specified resource. Otherwise, the current value of the soft limit for the specified resource is printed, unless the `-H' option is supplied.

When setting new limits, if neither `-H' nor `-S' is supplied, both the hard and soft limits are set.

Values are in 1024-byte increments, except for `-t', which is in seconds, `-p', which is in units of 512-byte blocks, and `-n' and `-u', which are unscaled values.

The return status is zero unless an invalid option is supplied, a non-numeric argument other than unlimited is supplied as a limit, or an error occurs while setting a new limit.

ulimit is a bash built in command.

Ulimit命令
设置限定能够把命令加到profile文件里,也足以在/etc/security/limits.conf文件中定义
限制。
指令参数
-a 展现全部限定
-c core文件大小的上限
-d 进度数据段大小的上限
-f shell所能创设的文件大小的上限
-m 驻留内部存款和储蓄器大小的上限
-s 货仓大小的上限
-t 每秒可占用的CPU时间上限
能够把命令加到profile文件里,而贰个经过中可用的内部存款和储蓄器空间唯有2G。-p 管道大小
-n 张开文件数的上限
-u 进程数的上限
-v 设想内部存款和储蓄器的上限
除可用乌利mit命令设置外,也足以在/etc/security/limits.conf文件中定义约束。
domino type item value
domino是以符号@带头的客户名或组名,*意味着具备客户,type设置为hard or soft。item指
定想约束的能源。如cpu,core nproc or maxlogins。value是呼应的约束值。

系统限定私下认可值

[root@flyinweb ~]# ulimit -a 
core file size (blocks, -c) 0 
data seg size (kbytes, -d) unlimited 
scheduling priority (-e) 0 
file size (blocks, -f) unlimited 
pending signals (-i) 32764 
max locked memory (kbytes, -l) 32 
max memory size (kbytes, -m) unlimited 
open files (-n) 1024 
pipe size (512 bytes, -p) 8 
POSIX message queues (bytes, -q) 819200 
real-time priority (-r) 0 
stack size (kbytes, -s) 10240 
cpu time (seconds, -t) unlimited 
max user processes (-u) 32764 
virtual memory (kbytes, -v) unlimited 
file locks (-x) unlimited

[root@flyinweb ~]# lsb_release -a 
LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch 
Distributor ID: CentOS 
Description: CentOS release 5.2 (Final) 
Release: 5.2 
Codename: Final

linux 系统中单个进度的最大线程数有其最大的界定 PTHREAD_THREADS_MAX

那么些界定能够在 /usr/include/bits/local_lim.h 中查看

对 linuxthreads 那个值平日是 1024,对于 nptl 则未有硬性的限量,仅仅受限于系统的能源

这些类别的能源入眼正是线程的 stack 所占领的内部存款和储蓄器,用 ulimit -s 能够查阅私下认可的线程栈大小,经常意况下,那些值是 8M

能够写生机勃勃段轻易的代码验证最多能够创设多少个线程

int main() { int i = 0; pthread_t thread; while (1) { if (pthread_create(&thread, NULL, foo, NULL) != 0) return; i ++; printf("i = %dn", i); } }

侦察呈现,在 linuxthreads 上最多能够创立 381 个线程,之后就能够回来 EAGAIN

在 nptl 上最多能够创立 382 个线程,之后就能够回来 ENOMEM

其风度翩翩值和辩驳完全适合,因为 32 位 linux 下的经过顾客空间是 3G 的轻重,约等于 3072M,用 3072M 除以 8M 得 384,然而实际代码段和数据段等还要占用部分空中,这几个值应该向下取整到 383,再减去主线程,获得 382。

这怎么 linuxthreads 上还要少贰个线程呢?那可太对了,因为 linuxthreads 还索要几个拘押线程

为了突破内部存款和储蓄器的节制,能够有二种办法

1卡塔尔 用 ulimit -s 1024 减小暗许的栈大小
2) 调用 pthread_create 的时候用 pthread_attr_getstacksize 设置二个非常小的栈大小

要留意的是,就算那样的也力所比不上突破 1024 个线程的硬限定,除非重新编译 C 库

连锁内容:

大器晚成、2.4基石与2.6水源的重要差距 
在 2.4水源的一花独放系统上(AS3/途乐H9),线程是用轻量进度完结的,各类线程要占用一个经过ID,在服务器程序上,如若遇上高点击率访谈,会形成进度表 溢出,系统为了珍视溢出的进度表,会有停顿的暂停服务场馆,而2.6内核就不会发生由于大量线程的始建和销毁导致进度表溢出的难点

二、线程结束必得自由线程货仓 
就是说,线程函数必需调用pthread_exit(卡塔尔(英语:State of Qatar)结束,不然直到主进度函数退出才放走,极其是2.6内核情况,线程创设速度高速,一超大心立时内存被 吃光,那点反倒是2.4功底蒙受好,因为2.4基石创立的是经过,何况线程成立速度比2.6内核慢多少个数据级。特别提示,在63位CPU,2.6内核成立线程的速度愈来愈疯狂,要是太快的话,加上usleep (卡塔尔暂停一小点时刻相比较好

三、不要编必要锁的线程应用 
唯有那些不要求互斥量的次序本领最大限度的行使线程编制程序带来的收益,不然只会越来越慢,2.6内核是抢占式内核,线程间分享冲突暴发的可能率远比2.4基石情状高,特别要注意线程安全,不然固然是单CPU也会发生莫明其妙的内部存款和储蓄器分歧台(CPU的高速缓存和主存内容不等同),英特尔的新CPU为了品质使用 NUMA结构,在线程编制程序中料定要注意断长续短。

四、单进度服务器最大并发线程数与内部存款和储蓄器 
很有意思,在默许的ulimit参数下,不修正内核头文件 
AS3 512M内部存款和储蓄器最多1000并发不仅连接 
CentOS4.3 512M内部存款和储蓄器最多300并发不仅仅连接 
就像是是CentOS比不上AS3,这里最主要缘由是ulimit的安顿变成,五个系统暗许的计划差距不小,要想单进度维持更八线程选择并发连接,将在硬着头皮减弱ulimit -s的参数,插越来越多的内部存款和储蓄器条,单进度服务器上二〇〇四并发一点都轻松,POSIX私下认可的限量是每经过64线程,但NTPL并不是纯正POSIX,不必理会那个约束,2.6内核下真正的范围是内部存款和储蓄器条的插槽数目(恐怕还大概有买内部存款和储蓄器的钱数)

最近几天的编制程序中,注意到在叁十六个人x86平台上2.6内核单进度创制最大线程数=VIRT上限/stack,与总内部存款和储蓄器数关系非常小,34人x86系统暗中认可的 VIRT上限是3G(内部存款和储蓄器分配的3G+1G主意),默认stack大小是10240K,因而单进度创制线程暗许上限也就300(3072M / 10240K),用ulimit -s 校正stack到1024K则使上限升到大意3050。笔者手头未有陆十几人系统,不理解2.6内核在六十二个人上单进程创制线程上限(实际上是本身懒得在同事的 机器上装fc4_x86_64)。

前几日买了黄金年代套廉价的61个人x86系统(六十七人赛杨+杂牌915主板卡塔尔,安装了CentOS4.3的x86_64本子,跑了贰遍上边包车型大巴小程序,得到的结果是:在ulimit -s 4096的意况下,单进度最大线程数在16000多或多或少,用top看 
VIRT 的上限是64G,约等于38个人, cat /proc/cpuinfo的结果是:address sizes : 36 bits physical, 48 bits virtual, 和自家想像的科班六13位系统不一致, 小编间接认为六12个人系统的内部存款和储蓄器空间也是61个人的 
附注1: 
单 位里某BSD FANS用AMD64笔记本跑小程序测验线程创立速度(线程成立后迅即phread_detach()然后跟随pthread_exit(卡塔尔(英语:State of Qatar),共计 100万个线程),肖似源码OpenBSD竟然比FreeBSD快了3倍,曾几何时OpenBSD也变得疯狂起来了?