前言
话不多说,先来张脑图~
linux 虚拟内存知识回顾
虚拟内存空间长啥样
在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的系统,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,如下所示:
通过这里可以看出:
32 位虚拟内存空间
通过这张图你可以看到,用户空间内存,从低到高分别是 6 种不同的内存段:
在上面的内存段中,堆和文件映射段的内存是动态分配的。比如说,使用 C 标准库的malloc()或者mmap(),就可以分别在堆和文件映射段动态分配内存。
64 位虚拟内存空间
我们知道在 32 位机器上,指针的寻址范围为 2^32,所能表达的虚拟内存空间为 4 GB。
那么我们可能会认为在 64 位机器上,指针的寻址范围为 2^64,所能表达的虚拟内存空间为 16 EB 。虚拟内存地址范围为:0x0000 0000 0000 0000 0000 - 0xFFFF FFFF FFFF FFFF 。
事实上在目前的 64 位系统下只使用了 48 位来描述虚拟内存空间,寻址范围为 2^48 ,所能表达的虚拟内存空间为 256TB。
从上图中我们可以看出 64 位系统中的虚拟内存布局和 32 位系统中的虚拟内存布局大体上是差不多的。
创建一个线程需要消耗多大虚拟内存
前面我们也介绍了栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。当然系统也提供了参数,以便我们自定义大小;
现在我们来验证一下,执行 ulimit -a 这条命令,查看进程创建线程时默认分配的栈空间大小
影响一个进程可创建多少线程的条件
虚拟内存空间上限
32位系统
在 32 位 Linux 系统里,一个进程的虚拟空间是 4G,内核分走了1G,用户能用的只有 3G。
创建一个线程需要占用 8M 虚拟内存,总共有 3G 虚拟内存可以使用。于是我们可以算出,最多可以创建差不多 380个(3G/8M)左右的线程。
如果想使得进程创建上千个线程,那么我们可以调整创建线程时分配的栈空间大小,比如调整为 512k:
[ecs-user@iZ2ze923utbhhwxwgc0pd9Z ~]$ ulimit -s 512
64位系统
64 位系统意味着用户空间的虚拟内存最大值是 128T,这个数值是很大的,一个线程需占用 8M 栈空间的情况来算,那么理论上可以创建 128T/8M 个线程,也就是 1000多万个线程,有点魔幻!
所以按 64 位系统的虚拟内存大小,理论上可以创建无数个线程。
系统参数限制
前面学习我们了解到了64 位系统的虚拟内存大小,理论上可以创建无数个线程。不过事实上,肯定创建不了那么多线程,除了虚拟内存的限制,还有系统的限制。
比如下面这三个内核参数的大小,都会影响创建线程的上限:
总结
最后简单总结下:
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://jmbhsh.com/toutiao/35097.html