当前位置: 代码迷 >> 综合 >> 栈、堆、内存空间(虚拟 )
  详细解决方案

栈、堆、内存空间(虚拟 )

热度:86   发布时间:2024-01-12 21:43:35.0

栈(stack)

  • 为编译器自动分配和释放,速度快,(如函数参数、函数返回地址,局部变量、临时变量等等)

  • 栈的特性:后入先出LIFO
    栈需要存储函数中的局部变量和参数,函数又是最后调用的最先销毁,栈的后进先出正好满足这一点。

  • 栈由高地址向低地址扩展,栈内是连续分配内存的。
    如果给一个数组或对象分配内存,栈会选择还没分配的最小的内存地址给数组,在这个内存块中,数组中的元素从低地址到高地址依次分配(不要和栈的从高到低弄混了)。所以数组中第一个元素的其实地址对应于已分配栈的最低地址。

  • 栈只能获取栈顶的内存地址
    所以如果栈是从高地址往低地址扩展的话,正好栈顶指向数组的起始地址,即数组的指针。而如果栈还采用从低地址到高地址扩展,那么不会指向数组的指针。

堆(heap)

  • 自由分配,自己申请,自己释放(否则发生内存泄漏),速度较慢,更灵活
  • 堆的特性:先入先出FIFO
  • 堆的内存地址是不连续的,由低地址向高地址扩展,一般是链表结构。

内存地址空间(虚拟)

  • 每个进程都会分配4G空间,都有同样的虚拟地址,但是由于映射的物理内存地址不同, 所以不会冲突。

  • 需要用到的指令和数据会传入物理内存,暂时不用的会根据算法临时存放在硬盘的页交换区

  • 之所以是4G,因位在32位架构下,一个指针的大小是4字节(4*8=32),2的32次方正好是4G寻址能力(每个地址单元是字节Byte)

  • 32位windows下,一个进程空间4G,内核占2G,留给用户只有2G,一个线程默认栈是1M,所以一个进程最大开2048个线程。当然内存不会完全拿来做线程的栈,所以最大线程数实际值要小于2048,大概2000个。

  • 32位Linux下,一个进程空间4G,内核占1G,用户留3G,一个线程默认8M,所以最多380个左右线程。(ps:ulimit -a
    查看电脑的最大进程数,大概7000多个)

  • 虚拟内存一般分为以下4大块:
    1,栈空间:特点是由系统管理,先进后出,里面放了局部变量、函数形参、自动变量。
    2,堆空间:特点是由用户管理,先进后出,我们可以用malloc、ralloc、calloc来分配空间。
    3,数据段:数据段里面又分三块,
    第一块是bss,保存未初始化的全局变量;
    第二块是rodata,保存了常量;
    第三块 是.data(静态数据区)保存了初始化的全局变量还有static修饰的变量。
    4,代码段:存放了源代码。