JS内存管理

2022/1/4 7:09:34

本文主要是介绍JS内存管理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

内容概要:

在程序运行中,性能优化是必不可少的。从认识内存空间的使用,到垃圾回收的机制,一步步地写出更高效的代码

  • 内存管理
  • 垃圾回收与常见GC算法
  • V8引擎的垃圾回收
  • Performance工具
  • 代码优化示例

内存管理介绍:

  • 内存: 由可读写单元组成, 表示一片可操作空间
  • 管理: 人为的去操作一片空间的申请、使用和释放
  • 内存管理: 开发者主动申请空间、 使用空间、 释放空间
  • 流程: 申请-使用-释放

JS中的内存管理

JS中的内存管理是自动进行的,没有相关API去进行实现,以下内容就可以看做是JS中的内存管理流程

  • 申请空间

    //声明变量就可视为申请空间
    let obj = {}
    
  • 使用空间

    //对变量的读写操作可视为使用空间
    obj.name = "zoe"
    console.log(obj.name)
    
  • 释放空间

//把使用不到的变量手动置为空
obj = null

JS中的垃圾回收

JS中的垃圾定义:
  • 对象不再被引用时是垃圾
  • 对象不能从根(全局对象)上访问到时是垃圾
JS中的可达对象
  • 可以访问到的对象就是可达对象(引用, 作用域链)
  • 可达的标准就是从出发能否被找到
  • JS中的根可以理解为全局变量对象

JS中的垃圾回收就是找到垃圾, 让内存引擎去回收这些空间

function objGroup (obj1, obj2) {
    obj1.next = obj2
    obj2.prev = obj1

    return {
        o1: obj1,
        o2: obj2
    }
}

let obj = objGroup({name:' obj1'}, {name: 'obj2'})
console.log(obj)
//此时obj, obj1, obj2都是可达对象,在全局对象上都是可以找到的

在这里插入图片描述

function objGroup (obj1, obj2) {
    obj1.next = obj2
    obj2.prev = obj1

    return {
        o1: obj1,
        o2: obj2
    }
}

let obj = objGroup({name:' obj1'}, {name: 'obj2'})
console.log(obj)
//把关于obj1的引用都删除掉,obj1就会被认为是垃圾,从而被JS引擎回收
delete obj.o1
delete obj.o2.prev

在这里插入图片描述

GC算法介绍:

GC中的垃圾是什么
  • 程序中不再需要使用的对象
  • 程序全局变量对象中不能再访问到的对象
GC算法是什么
  • GC是一种机制,垃圾回收器完成具体的工作
  • 工作的内容就是查找垃圾释放空间、回收空间
  • 算法就是工作时查找和回收所遵循的规则
常见GC算法
  • 引用计数
  • 标记清除
  • 标记整理
  • 分代回收(V8引擎)

引用计数算法:

实现原理:

​ 为当前对象设置引用数,判断当前对象引用数是否为0,如果为0,就将该对象进行回收,以释放空间和再分配

引用计数器:

引用关系改变立即修改引用数字,为0时清除该对象

//user1 user2 user3都被list变量引用
const user1 = { num: 12}
const user2 = { num: 23}
const user3 = { num: 24}

const list = [user1.num, user2.num, user3.num]

function fn(){
    //fn执行完毕,内部声明的变量num1 num2都会被清除
    const num1 = 1
    const num2 = 2
}

fn()
优点:
  • 发现垃圾立即回收(一旦引用数为0,就会被回收)
  • 最大限度减少程序暂停(一旦内存告急,就会去查找引用数为0的对象,以释放空间)
缺点:
  • 无法回收循环引用的对象(且回收判断依据是引用数是否为0,即使是不可达对象,引用数不为0 也不会被清除掉)
  • 每次赋值都要去计算相关的引用数,时间开销大
let obj1 = {name: 'luffy'}
let obj2 = {name: 'zoe'}
obj1.ref = obj2
obj2.ref = obj1
//此时obj1和obj2互相引用,且没有别的地方再去引用他们,因为他们的引用数都不是0, 就都不会被回收掉

标记清除算法

  • 核心思想: 分标记清除两个阶段完成
  • 遍历所有对象找标记活动对象
  • 遍历所有对象清除没有标记的对象
优点:
  • 相对于引用计数算法,会清理掉不可达对象
缺点:
  • 回收后释放的空间在地址上是不连续的,可能导致释放的空间无法被使用

在这里插入图片描述

在这里插入图片描述

标记整理算法

标记整理算法可以看做是标记清除算法的增强版

流程:
  • 标记阶段按的操作与标记清除算法一致
  • 清除阶段会先进行内存空间的整理,移动对象位置, 然后再清除非活动对象

在这里插入图片描述

在这里插入图片描述



这篇关于JS内存管理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程