# 计算机基础概念 ## 计算机基础概念 计算机世界里,为什么要区分堆内存和栈内存呢? 在计算机诞生初期,程序运行过程中,没有栈帧需要维护的,那时也没有函数function的区分。内存采取的是静态分配策略,这比动态分配内存要快,但是却不够灵活。程序内部的数据结构大小必须在编译器Compile阶段确定,在运行时也无法动态扩展内存。 内存地址范围被编号为0x0000到0xFFFF,假设是16位内存。 ``` =============== 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左右已经足够使用。编译器一般都直接限制栈的大小 - 多线程导致有多个栈,所以堆-栈的两端分割模式是不合适的,每个栈应当有界