1. call stack
维基百科关于call stack的介绍中,举了这么一个例子:DrawSquare()
调用DrawLine()
,此时stack frame的结构如图所示。
从图中我们可以能够得到这些信息:
- 当前被调用,正在执行还没有
return
的DrawLine
函数在stack的顶部; - 一个stack frame对应一个被调用并且没有结束的函数,
DrawLine
和DrawSquare
分别都有自己的stack frame; - 每一个frame包含local variable, return address(当这个被调用函数结束时,程序需要回到哪一行代码,其实就是调用它的函数的下一行地址), parameters;
- 当函数结束时,其对应的stack frame pop off the call stack, 出栈。
从工作机制中,我们可以引申思考出的结论:
- 这个工作机制能够很容易地解释:在函数内部定义的local variable为什么在函数结束时就“消失”了。因为它们在call stack对应的stack frame中,一旦函数出栈,这些内存也就被释放了。
- 一个program/task/thread会被分配一个call stack?(不太确定)
2. 内存区
在程序运行的时候,操作系统分配的内存可以粗略划分为:栈区,堆区,代码区,静态存储区。
let a=1;
let user={name: "John"};
在JS中,存放primitive value的variable都会被放在栈区,如上述代码中的a
,user
也存放在栈区,但是它存放的是一个地址,一个引用(reference)。通过user
我们可以access定义在heap(堆内存)中的对象数据块。
网友评论