目录

计算机基础概念

计算机基础概念

计算机世界里,为什么要区分堆内存和栈内存呢? 在计算机诞生初期,程序运行过程中,没有栈帧需要维护的,那时也没有函数function的区分。内存采取的是静态分配策略,这比动态分配内存要快,但是却不够灵活。程序内部的数据结构大小必须在编译器Compile阶段确定,在运行时也无法动态扩展内存。

内存地址范围被编号为0x0000到0xFFFF,假设是16位内存。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
===============     Highest Address (e.g. 0xFFFF)
|             |
|    STACK    |
|             |
|-------------|  <- Stack Pointer   (e.g. 0xEEEE)
|             |
.     ...     .
|             |
|-------------|  <- Heap Pointer    (e.g. 0x2222)
|             |
|    HEAP     |
|             |
===============     Lowest Address  (e.g. 0x0000)

早期的计算机系统,内存并没有现在这么大,动不动就32G,64G,那时候只有几十KB大小,那么内存要放置静态代码,静态数据,剩余的区域就需要动态数据,和可增长的栈。一个有用的方案是把动态变化的数据结构放在内存地址两端,两者向中间增长。一个从0x0000增加,一个从0xFFFF减小。

早期的机器,一般都是从0地址启动,载入bootcode,所以从内存布局上,从0地址依次放置静态代码,静态数据,动态数据,动态的栈,这里的栈从高地址向低地址增长。

现代程序

随着编程技术的发展,现代程序逐渐具备下列特征,导致内存布局问题中的单个栈增长方向无所谓。

  • 使用线性虚拟地址,进程空间为4G或者更高
  • 现代程序写法,栈的大小1M左右已经足够使用。编译器一般都直接限制栈的大小
  • 多线程导致有多个栈,所以堆-栈的两端分割模式是不合适的,每个栈应当有界