声明:Q&A系列的文章是我在平时自己遇到的或者看到的一些问题,本着再小的问题也需要有人解答的想法,将这些问题和答案整理出来。
欢迎和我讨论问题,同时也欢迎转载Q&A系列的文章。
先介绍一下内存的分段机制:
在虚拟内存中,一个程序为了方便共享和保护,就会使用分段。分段是把一个程序分成独立的地址空间,每个段都有自己的基址和长度,在纯分段系统给中,段内地址是一段连续的内存,在段页式系统中,段内地址也分成页号和页内地址,允许离散的分配空间。
gcc在编译程序的时候,把程序分成了很多个段,下面是几个比较经典的段:
上面这个图是从上到下,代表的是从高地址到低地址。
.env段:存放这环境变量和gcc赋予程序的一些变量。
.stack:很明显这个就是栈啦,栈里面存放着局部变量。
shared memory段:这个段存放着要使用的动态链接库的函数,比如很常见的printf.o 和 malloc.o
.bss段:这里存放的是没有被初始化的静态变量,这个段会在程序开始运行的时候被初始化为0.
.data段:这里存放这已经被初始化的静态变量。
.text:这个段也叫正文段,里面存放着程序的正文,你的exe文件的二进制指令。这段是只读的,这个程序的所有进程共享这个正文段。
.rodata:这个段也叫常量区,常量区里面存放着没有名字的常量,最常见的就是字符串常量,
关于stack和heap:
1.stack和heap的生长和大小
stack是从高地址向低地址生长的,heap是从低地址向高地址生长的。线程中的栈的大小一般是8M,而进程的栈大小一般是比线程栈大,但是不会超过线程栈的两倍。在linux下使用 命令
ulimit -s
可以查看一个线程栈的默认大小。
而一个进程中的堆的大小是一般是可以很大的,可以达到虚拟内存大小。
2.一个进程可以用多少个线程栈?