专栏首页前端有的玩js垃圾回收机制原理给你聊的明明白白

js垃圾回收机制原理给你聊的明明白白

前言

大多数语言都是提供自动内存管理机制,比如C#、Java,JavaScript。自动内存管理机制也就是我们经常听到的垃圾回收机制 。好神奇哦,语言会收垃圾,哈哈?,不过这里的垃圾,可不是家里面的厨余垃圾啥的,而是 一些不再使用的变量所占用的内存。我们的js的执行环境会自动对这些垃圾进行回收,也就是释放那些不再使用的变量所占用的内存,收垃圾的过程 会按照固定的时间间隔周期性的执行 垃圾回收

内存泄露

如果 那些不再使用的变量所占用的内存 没有被释放 会怎样呢??? 那就会造成 内存泄露

什么是内存泄露???别着急往下看

内存泄露其实就是我们的程序中已经动态分配的堆内存,由于某些原因没有得到释放,造成系统内存的浪费导致程序运行速度减慢甚至系统崩溃等严重后果。后果很严重的哦,现在知道为啥要有垃圾回收机制了嘛

垃圾回收机制

看看这个代码可以加深理解垃圾回收机制哦☺

let name = 'Symbol卢';
function aboutMe() {
  let hobby = '吃肉肉';
  let say=`我是${name},我喜欢${hobby}`;
  console.log(say);
}
aboutMe()

在函数 aboutMe() 执行的时候,声明了两个局部的变量 hobbysay ,等函数执行完毕之后,这两个局部变量也就不再使用 ,所以垃圾回收机制 就会将不再使用的(局部)变量 hobbysay 清除掉 (释放了它们的内存)

在js中能实现这样的垃圾回收的功能的一共有两种方式:标记清除引用计数

标记清除

标记清除是js中最常用的垃圾回收方式。它的原理也比较好理解,废话不多说,先上代码

function speakLines(){
  let night="天黑";//做个标记 ,进入环境 
  let closeEyes="闭眼";//做个标记 ,进入环境 
  let speak=`开始狼人杀,${night}请${closeEyes}`;//做个标记 ,进入环境 
  console.log(speak);
}
speakLines() //代码执行完毕  里面被标记过的变量,又被标记 离开环境 最后被回收

当代码执行在一个环境中时(例如上面的 speakLines函数),每声明一个变量,就会对该变量做一个标记(例如标记一个进入执行环境);当代码执行进入另一个环境中时,也就是要离开上一个环境( speakLines 函数执行完毕,去执行其他的函数),这时对上一个环境中的变量做一个标记,(例如标记一个离开执行环境),等到垃圾回收执行时,会根据标记来决定要清除哪些变量进行释放内存

引用计数

引用计数是一种不太常用的垃圾回收方式。同样也是先上代码再说原理

let skill = ["唱歌", "弹吉他", "播音"]
function change() {
  let new_skill = ["vue", "react", "node", "webpack", ".net", "mysql", "sqlServer", "nginx"];
  skill = new_skill;
  //一个文艺小青年就这样的变成了一个技术宅男
}
change()
console.log(skill)  //返回  ["vue", "react", "node", "webpack", ".net", "mysql", "sqlServer", "nginx"]

change()内部声明了一个局部变量 new_skill,并将一个引用类型 的数组 赋值给它,同时又将变量new_skill赋值给了全局变量 skill,此时,这个局部变量 new_skill 就不会被当成垃圾回收了。啊,为什么呢??? 还记得我们在上面说过的 垃圾回收,回收的是那些不再使用的变量,释放它们的内存,因为此时的局部变量 new_skill 并不是一个 不再使用 的局部变量了,它被全局变量 skill所引用了( 还在使用),所以就不会被回收了。

上面的这一过程,使用的就是引用计数的垃圾回收方式

引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值的引用次数减1,当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,当垃圾回收的时候,就会将 引用次数为0的进行回收,释放对应的内存

let skill = ["唱歌", "弹吉他", "播音"]
function change() {
  let new_skill = ["vue", "react", "node", "webpack", ".net", "mysql", "sqlServer", "nginx"];//被引用次数为0 
  skill = new_skill; ////被引用次数为1
}
change()
console.log(skill) 

管理内存

在我们的项目中,我们肯定是想要用更少的内存,来使得页面有更好的性能。这个时候就需要我们来手动的管理内存了,及时的去释放数据的引用。我们可以只将需要的数据,存入变量。一旦这个数据不再使用了,我们需要手动的给变量赋值 null 来释放数据的引用。(-------解除引用) 大多需要我们进行手动的解除引用的都是一些全局的变量,因为局部的变量,在离开环境的时候就会被自动清除了。

let skill = ["唱歌", "弹吉他", "播音"]
function change() {
  let new_skill = ["vue", "react", "node", "webpack", ".net", "mysql", "sqlServer", "nginx"]
  skill = new_skill;
  //一个文艺小青年就这样的变成了一个技术宅男
}
change()
console.log(skill) 
skill = null;//将不再使用的变量进行赋值 unll  来释放数据引用

change() 内部声明的局部变量 new_skill 被全局变量 skill 所引用,所以此时变量 new_skill 的引用次数为1,为了让变量 new_skill 被清除引用,在代码的最后一行,赋值一个 null 给全局变量 skill,手动解除了变量 skill 对变量 new_skill 的引用,此时变量 new_skill 的引用次数 减1,所以 当前 new_skill的引用次数为0了。当垃圾回收机制执行的时候,发现 new_skill 的引用次数为 0,就把该变量当成无用变量给清除了,释放了内存,提高了性能。

本文分享自微信公众号 - 前端有的玩(gh_918bae0a9616)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java垃圾回收机制你还不明白?一线大厂面试必问的!

    自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。

    程序员追风
  • V8 引擎垃圾回收与内存分配

    ? 这是第 82 篇不掺水的原创,想要了解更多,请戳上方蓝色字体:政采云前端团队 关注我们吧~

    政采云前端团队
  • day038:V8 引擎如何进行垃圾内存的回收?

    JS 语言不像 C/C++, 让程序员自己去开辟或者释放内存,而是类似Java,采用自己的一套垃圾回收算法进行自动的内存管理。作为一名资深的前端工程师,对于JS...

    用户3806669
  • 面试官:你说你熟悉jvm?那你讲一下并发的可达性分析

    那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片。看到这张图片的时候我就很开心,多鲜活、多舒服的画面呀。

    why技术
  • Kafka如何通过精妙的架构设计优化JVM GC问题

    “ 这篇文章,同样给大家聊一个硬核的技术知识,我们通过Kafka内核源码中的一些设计思想,来看你设计Kafka架构的技术大牛,是怎么优化JVM的GC问题的?

    chinotan
  • 浅谈js的内存与闭包0.前言1.先说类型2.再说顺序3.然后到了函数4.接着是临时空间5.垃圾回收6.IIFE和闭包

    主要结合了内存的概念讲了js的一些的很简单、但是又不小心就犯错的地方。 结论:js执行顺序,先定义,后执行,从上到下,就近原则。闭包可以让外部访问某函数内部变量...

    lhyt
  • 前端面试:谈谈 JS 垃圾回收机制

    最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B ...

    Fundebug
  • 前端面试:谈谈 JS 垃圾回收机制

    最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B ...

    前端小智@大迁世界
  • 干货 | WeakMap的特性及应用场景

    “ 我们先从 WeakMap 的特性说起,然后聊聊 WeakMap 的一些应用场景。 ”     特性     1. WeakMap 只接受对象作为键名  ...

    腾讯NEXT学位
  • 重学前端(三)-聊聊我们的浏览器的那些事

    最近公司比较忙,加上重磅好剧隐秘的角落来袭,重学前端系落下了,最近闲来无事,续上!作为一名前端工程师,除了编辑器,浏览器当然使我们打交道最多东西,虽然我们每天都...

    用户7413032
  • 【本周主题】第三期 - JavaScript 内存机制

    早高峰的电梯,挤满了人,先进去的要想出来,后进去的是不是要先出来让路?就是这个道理吧。。。

    xing.org1^
  • 前端面试:谈谈 JS 垃圾回收机制

    最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B ...

    Javanx
  • 视野前端(二)V8引擎是如何工作的

    许多同学在阅读了基础进阶系列文章之后,对JS代码的执行顺序理解得更清晰了。可也有不少好学的大佬在此基础上进一步思考,JS引擎到底是如何工作的?什么时候解析?什...

    用户6901603
  • 吐血整理的垃圾回收知识

    今天的肝货来了,作者已经肝吐血了,看书查资料整理了8000字的垃圾回收相关知识,虽然很长,可能会花费你20分钟左右的阅读时间,但是看完相信你一定会有很大的收货,...

    Java宝典
  • 前端基础进阶(一):JavaScript 内存空间详细图解

    因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念,很容易被大家忽视。特别是很多不是计算机专业的朋友在进入到...

    一只图雀
  • 画说 Ruby 与 Python 垃圾回收

    本文基于我在刚刚过去的在布达佩斯举行的RuPy上的演讲。我觉得趁热打铁写成帖子应该会比只留在幻灯片上更有意义。你也可以看看演讲录像。再跟你说件事,我在Ruby大...

    goodspeed
  • 让你虎躯一震的垃圾代码分类指南

    其实每个行业都会存在各种各样糟糕的情况,娱乐性的分类会将问题放大,让我们能站出来用另一个视角来看看,什么类型的程序员是我们应该避免的。

    帅地
  • JVM系列开篇:为什么要学虚拟机?

    跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看。所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试。但我经过了...

    陈树义
  • 程序员垃圾代码分类指南

    上一篇文章《程序员垃圾分类图鉴》和大家聊了聊程序员的垃圾分类,有的程序员直呼太真实,有的程序员觉得太讽刺,不应该给程序员进行这样的分类。

    纯洁的微笑

扫码关注云+社区

领取腾讯云代金券