JS性能优化之内存管理

484 阅读3分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

前言

随着近些设备的发展,许多语言都有自己的内部GC机制,所以这样的一些变化,让我们不需要特别注意内存空间的情况下,也可以进行开发,所以为什么要重提内存管理呢?

内存为什么需要管理?

在我们学习闭包的时候,很经常提到一句话

闭包引用另外一个函数的活动对象,因此这个活动对象无法被销毁,这意味着,闭包比一般的函数需要更多的内存消耗。尤其在IE浏览器中需要关注。由于IE使用非原生javascript对象实现DOM对象,因此闭包会导致内存泄露问题

说白了就是没有用好闭包的话就会造成内存泄漏

其实不仅仅是闭包,对于一个页面来说,任何没有使用到的内存,没有得到及时的释放,都会造成内存泄漏。或许你可以说我们现在的电脑很强大,一点点的内存泄露顶的住,但是内存泄漏堆积就可能会导致内存溢出.

内存泄漏会导致什么问题

  • 内存泄漏会导致页面卡顿,甚至无响应。
  • 内存溢出会导致程序运行时直接报错。

内存管理的介绍

  • 内存:由可读写单元组成,表示一片可操作空间
  • 管理:人为的去操作一片空间的申请、使用、释放 所以总而言之: 内存管理就是开发者去主动申请空间、使用空间、释放空间

那么这样一来管理流程就很明确了: 申请 -> 使用 -> 释放

js中的内存管理机制

由于js没有对应的api让我们进行内存回收,所以我们可以这样做

// 申请
let obj = {}
// 使用
obj.name = '-'
// 回收
obj = null

JavaScript中的垃圾回收

对于JavaScript,他的内存管理是自动的,那对于JavaScript什么是垃圾呢?

  • 对象不再被引用时就是垃圾
  • 对象不能从根上访问到时是垃圾

JavaScript的引用和可达对象

什么是可达对象?

  • 可以访问到的对象就是可达对象(引用、作用域链)
  • 可达的标准就是从根出发是否能够被找到 这么多次提到,那什么是呢?

根的定义

Javascript中的根就可以理解为是全局变量对象

让我们用代码表示一下什么是引用什么是可达

let obj = {
    name: 'xm'
}

写完这一段的代码之后,从代码的角度来说 {name: 'xm'}我们可以说:这个空间被 obj引用了! 站在这个全局空间下我们是可以访问到obj的,那就说明obj是可达的,那 {name: 'xm'}也是可达的。

那我们再来一点操作:

let obj = {
    name: 'xm'
}
let ali = obj

这里我们可以认为{name: 'xm'}又多了一次引用,所以说这里let ali = obj存在引用数值变化的。

那我们回收一下obj的空间

let obj = {
    name: 'xm'
}
let ali = obj
obj = null

随着obj = null的操作,obj访问 {name: 'xm'}已经被断掉了,那{name: 'xm'}是否还是可达呢? 答案是必然的!因为ali还引用了这个访问空间