js标记清楚的过程理解

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。
感觉这些话说的让我难以理解。尤其这句话(它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了)
请懂得老哥们不嫌麻烦就下面的例子解释一下这话的含义。谢谢了
function tes(){

var a =3;
var b= 2;
var c=a;            

}
tes()

阅读 4.1k
2 个回答

环境中的变量你可以理解为正在使用的变量。

这句话的意思是说,先认为所有对象都是要清除的,然后遍历正在使用的那些对象,以及由那些对象所引用的其他对象。所有这些对象都找出来之后,剩下的就是没有在使用的对象了,就可以被垃圾回收了。

标记清除的好处就是可以解决循环引用问题。a和b相互引用,引用计数都是1,所以只用引用计数的话两个都没办法回收。但是用标记清除就可以。

标记有用对象的过程其实就是可达测试的过程。你可以想象整个内存是一个大海,每个对象都是一个岛屿,相互之间用大桥连接,现在要找出与大陆相连的岛屿,那么就从大陆出发,依次标记所能达到的每个岛屿,最后没有被标记到的岛屿就是孤岛,可以当垃圾清除掉。即使两个孤岛之间相互有桥连接也没用,因为与大陆不通啊。

这个大陆就是应用程序,或者说是应用程序里的根对象。每次遍历的时候都是从这个根对象出发的。

不知道这么说你能明白吗?

最后再来说说你题目里那个例子。你那个例子是不恰当的,因为a b c三个变量都是临时变量,存在于栈中,会自动回收。它们的值是原始类型,不是对象,因此也不存在垃圾回收的问题。记住垃圾回收只作用于对象。

所以你的例子当函数执行完之后,这些临时变量和它们的值呼啦一下都没了,根本没有垃圾回收什么事儿。

标记清除分两个阶段:标记和清除
标记阶段将从 root 节点遍历所有变量,将无法访问的变量打上标记
清除阶段从 root 节点遍历所有变量,释放打上了标记的所有变量

无法访问的意思是从 root 节点开始没有办法直接访问或者间接访问
当然整个过程不止是标记清除这么简单,有兴趣可以看一下这里

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题