JS内存模型中,栈与堆是如何协同运作以实现高效内存管理的?
- 内容介绍
- 文章标签
- 相关推荐
栈和堆的基本角色
说实话,JS 的内存就像一间屋子。
那必须的! 栈是那张干净的桌子,东西一放就能马上找得到。
堆嘛,就是后院的储物箱,东西可以随意往里塞,也能随时搬出来。
这俩玩意儿配合得好,代码跑得飞快,页面也不容易卡。
栈到底装啥
出岔子。 先说基本类型:Number、 String、Boolean、 它们在函数调用时直接被压进栈顶,函数结束立马弹出。 主要原因是是后进先出,分配和回收都超省事——系统自己来你根本不用管。 哈哈,这就是所谓的“自动分配,自动释放”。 堆里住的是什么 对象、 数组、函数这些引用类型可不敢往桌子上摆太大块儿,于是被扔进堆里。 当你写let obj = {a:1}时实际在堆里开辟了一块空间存放{a:1}。 而栈里只留了一个指针,好比钥匙一样指向那块堆内存。 指针本身很小,所以栈依旧保持轻盈。 栈‑堆协同的工作流 想象你打开一个函数: 1)引擎先创建施行上下文,把基本类型变量直接放进栈。 2)碰到对象或数组,它会在堆里找空位,然后把地址塞进栈。 这样,你既能享受栈的高速,又拥有堆的灵活空间。 值拷贝 vs 引用拷贝 a = 10; b = a; b 在栈里复制了一份值,改 b 不会影响 a——这叫值拷贝。 x = {name:'Tom'}; y = x; x 和 y 各自的栈位都只是一把钥匙,都指向同一个堆对象。改 y.name 那是改了堆里的数据,x 也跟着变——这叫引用拷贝。 垃圾回收怎么搞定“堆”里的碎片 别看 GC 很神奇,它背后其实靠的是“可达性”原则。 根对象能追溯到的所有对象,都算活着;没法追到的,就算孤岛,被清理掉。 闭包是个常见坑:如果闭包一直被外部持有,它内部引用 中肯。 的变量永远不会被丢进垃圾箱——这就是泄漏的根源之一。
栈和堆的基本角色
说实话,JS 的内存就像一间屋子。
那必须的! 栈是那张干净的桌子,东西一放就能马上找得到。
堆嘛,就是后院的储物箱,东西可以随意往里塞,也能随时搬出来。
这俩玩意儿配合得好,代码跑得飞快,页面也不容易卡。
栈到底装啥
出岔子。 先说基本类型:Number、 String、Boolean、 它们在函数调用时直接被压进栈顶,函数结束立马弹出。 主要原因是是后进先出,分配和回收都超省事——系统自己来你根本不用管。 哈哈,这就是所谓的“自动分配,自动释放”。 堆里住的是什么 对象、 数组、函数这些引用类型可不敢往桌子上摆太大块儿,于是被扔进堆里。 当你写let obj = {a:1}时实际在堆里开辟了一块空间存放{a:1}。 而栈里只留了一个指针,好比钥匙一样指向那块堆内存。 指针本身很小,所以栈依旧保持轻盈。 栈‑堆协同的工作流 想象你打开一个函数: 1)引擎先创建施行上下文,把基本类型变量直接放进栈。 2)碰到对象或数组,它会在堆里找空位,然后把地址塞进栈。 这样,你既能享受栈的高速,又拥有堆的灵活空间。 值拷贝 vs 引用拷贝 a = 10; b = a; b 在栈里复制了一份值,改 b 不会影响 a——这叫值拷贝。 x = {name:'Tom'}; y = x; x 和 y 各自的栈位都只是一把钥匙,都指向同一个堆对象。改 y.name 那是改了堆里的数据,x 也跟着变——这叫引用拷贝。 垃圾回收怎么搞定“堆”里的碎片 别看 GC 很神奇,它背后其实靠的是“可达性”原则。 根对象能追溯到的所有对象,都算活着;没法追到的,就算孤岛,被清理掉。 闭包是个常见坑:如果闭包一直被外部持有,它内部引用 中肯。 的变量永远不会被丢进垃圾箱——这就是泄漏的根源之一。

