Lambda博客
  • 自我介绍
  • SSR
    • 浅谈SSR
  • React
    • 页面路由——React-Router
    • 管好你的状态——React-Redux
    • 一个哪行——React详解
    • 左膀右臂一个不少——React初探
  • 问题记录
    • js-xlsx实现纯前端导出excel表格
    • 前端开发需要了解的东西
    • 打造高性能网站
  • JavaScript学习笔记
    • 语法和API
    • js-垃圾回收
    • 收集的JS使用技巧
    • 执行机制
    • 原型和原型链
    • 执行上下文
    • 事件循环
    • JavaScript手写代码
    • 43道JS面试题
    • 悄悄的带走了你的东西——闭包详解
    • 你是个富二代吗?——JavaScript作用域链
    • 捉摸不透的女生——JavaScript类型转换
    • 这是你的女神!——JavaScript
  • 网络学习笔记
    • 强不强——HTTP-协商缓存VS强缓存
    • 网络缓存
    • 我要飞的更高——计算机网络
    • 快点!再快点!——CDN
    • 喜怒哀乐多状态——HTTP状态码
    • 你会爱上我的(ಥ_ಥ) ——TCP详解
    • 隔壁老王想篡位?门都没有——同源策略
  • 软技能
  • 安全专题
    • 保护好自己——网站安全,预防
  • 浏览器兼容性
    • 我是个好人——浏览器兼容性
  • 多图片加载——懒加载详解
  • 数据结构
  • Node
    • Node初探
  • Typescript
    • JS Plus 真香——初探 TypeScript
  • 设计模式
    • 不要花里胡哨,要一套一套——设计模式(1)
    • 学会“套路”——设计模式(2)
  • Vue
    • 实操实干——vue实例记录
    • 停下来,问问自己——Vue-刨根问底
    • 你有喘息的机会吗?——Vue,逐步了解
    • 你累吗?来来来,安利框架——Vue-初次见面
  • 小程序
    • 今天天气怎么样——记一次小程序开发
  • Webpack
    • 蛋糕分割整合工具——Webpack-前端工程化
  • 你一块,我一块——Web-modules 前端模块化
  • HTML5
    • 你会画小猪佩奇吗?—— canvas
    • 画个矢量图——HTML5-SVG
    • 听说你爱闹腾——HTML5-多媒体
    • 动画神器——HTML5-requestAnimationFrame
    • 留下痕迹——HTML5-客户端存储
    • 你知道指北针吗?——HTML5-DeviceMotionEvent
    • 你在哪啊?我在这啊——HTML5-Geolocation
    • 你到这,你到那——HTML5-拖拽
    • 你从这,到那——HTML5-拖拽上传文件
    • 开启前端之路——HTML 标签
  • 瀑布流(无限滚动)
  • 我是怎么来的?——浏览器渲染原理
  • Css
    • 由大变小,你行吗 —— 移动端
    • 动起来,这样比较炫—— CSS3 动画
    • 请不要拐弯抹角 —— CSS3 选择器
    • 想炫吗?—— CSS3 属性
    • 最后的最后——CSS自问自答
    • 万事开头难?——深入学习前端常见布局
    • 一入前端深似海——BFC剖析
    • 还有哪些好玩的东西——CSS提升
    • 那些好看的页面是怎么形成的——CSS 初识
  • 拿个小本本记下——Cookie
由 GitBook 提供支持
在本页
  • 垃圾回收
  • 内部算法
  • 哪些情况会引起内存泄漏
  • 垃圾回收优化
在GitHub上编辑
  1. JavaScript学习笔记

js-垃圾回收

垃圾回收

JavaScript 中的内存管理是自动执行的,而且是不可见的。

由于字符串,对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript 程序每次创建字符串、数组或对象时,解释器必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够再用,否则,JavaScript 的解释器将会消耗完系统中所有可用内存,造成系统崩溃

JavaScript 垃圾回收很简单:找到不再使用的变量,然后释放掉其占用的内存。但是这个过程不是实时的,因为开销比较大,所以垃圾回收器会按照固定的时间间隔周期性执行。

内部算法

标记清除

基本的垃圾回收算法称为 “标记-清除“,定期执行以下 “垃圾回收” 步骤

  • 垃圾回收器获取根并 “标记“ 他们

  • 然后它访问并 标记 所有来自他们的引用

  • 然后它访问标记的对象并标记他们的引用(所有被访问的对象都被记住,以便以后不再访问同一对象两次)

  • 以此类推,直到有未访问的引用(可以从根访问)为止

  • 除标记的对象外,所有对象都被删除

垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响

引用计数

在 JavaScript 引擎中有一个引用表,保存着内存里面所有的资源的引用次数。如果一个值的引用次数是 0,就表示这个值不再用到了,因此就可以将这块内存释放掉

如果一个值不再需要了,引用数却不为 0,垃圾回收机制无法释放这块内存,从而导致内存泄漏

// 循环引用
let obj = {}
let obj1 = {}

obj.a = obj1
obj1.a = obj1

要解决循环引用的问题,最好在不使用他们的时候手工将他们设置为空

obj = null
obj1 = null

哪些情况会引起内存泄漏

意外的全局变量

未被声明的变量会变成一个全局变量,在页面关闭之前不会被释放。

function fn() {
  a = 1
}

function fn2() {
  this.a = 2
}

被遗忘的计时器或回调函数

闭包

闭包可以维持函数内部的变量,使其得不到释放。

function bindEvent() {
  var div = document.createElement('div')
  div.onclick = function() {}
}

解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对 dom 的引用

// 将事件函数定义在外边
function onClickEvent() {
  // ...
}

function bindEvent() {
  var div = document.createElement('div')
  div.onclick = onClickEvent
}
// 删除对 dom 的引用
function bindEvent() {
  var div = document.createElement('div')
  div.onclick = function() {
    // ...
  }
  div = null
}

垃圾回收优化

数组优化

在清空一个数组项的时候优先使用.length = 0 的方式去清空数组,如果使用 =[] 的方式会将原来的数组对象变成一个内存垃圾

对象尽量复用

对象尽量复用,不用的对象尽可能设置为 null

var t = {}
for (let i = 0; i < 5; i++) {
  t.age = i++
  t.name = 'name' + i
  // 这里使用t,使用完之后不用的话可以置为null
}

t = null
上一页语法和API下一页收集的JS使用技巧

最后更新于3年前