Q:从内存模型角度分析执行代码的执行流程第二步看,在堆空间创建closure(foo)对象,它是存储在foo函数的执行上下文中的。
那么closure(foo)创建开始时是空对象,执行第三步的时候,才会逐渐把变量添加到其中。
当foo函数执行结束后,foo的执行上下文是不是销毁了?如果销毁了,产生以下两个疑问:如果foo函数执行上下文销毁了,closure(foo)并没有销毁,那foo函数执行上下文是怎么销毁的呢?就比如销毁一个盒子,盒子毁里,里面的东西应该也是毁掉的既然closure(foo)既然没有销毁,那它存储在堆中的什么地方呢?毕竟所依赖的foo执行上下文已经不存在了A:关于foo函数执行上下文销毁过程:foo函数执行结束之后,当前执行状态的指针下移到栈中的全局执行上下文的位置,foo函数的执行上下文的那块数据就挪出来,这也就是foo函数执行上下文的销毁过程,这个文中有提到,你可以参考“调用栈中切换执行上下文状态“图。
第二个问题:innerBar返回后,含有setName和getName对象,这两个对象里面包含了堆中的closure(foo)的引用。
虽然foo执行上下文销毁了,foo函数中的对closure(foo)的引用也断开了,但是setName和getName里面又重新建立起来了对closure(foo)引用。
你可以:打开“开发者工具”在控制台执行上述代码然后选择“Memory”标签,点击”take snapshot” 获取V8的堆内存快照。
然后“command+f”(mac) 或者 “ctrl+f”(win),搜索“setName”,然后你就会发现setName对象下面包含了 raw_outer_scope_info_or_feedback_metadata,对闭包的引用数据就在这里面。
Q:Function 函数类型也是继承于Object,声明函数后是不是也是存在堆空间中的,那么浏览器编译函数时是不是会同时创建执行上下文和向堆空间中压入一个值function a(){ var b = 1; var c = { d: 2 }; }当 a 的执行上下文销毁后,c 对象在堆空间中的引用会跟着销毁么,将 c 返回出去或不返回,会不会是不一样的情况A:函数就是一种特别的对象,所以会保存在堆上,编译函数时,这个函数就已经存在于堆中了!第二个问题返回了c对象的话,那么说明全局环境对c对象有引用,既然有引用那么就不会被垃圾回收器标记出来,所以c对象也就不会回收!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)