乐趣区

关于javascript:前端的内存处理

内存的生命周期

1. 内存调配:申明变量,函数,对象的时候,js 会主动调配
2. 内存应用:调用的时候
3. 内存回收:应用结束,js 判断

js 垃圾回收

1. 援用计数垃圾回收

 a 对象对 b 对象有拜访权限,则 a 援用 b 对象
没有援用对象则标记为垃圾
缺点:循环援用:a 援用 b,b 援用 a => 内存透露 

2. 标记革除算法

 在运行的时候给存储在内存的所有变量加上标记
从根部触发,能涉及的对象,标记革除
哪些有标记的视为行将删除的变量

js 常见的内存透露

1. 全局变量(赋值为 null,革除)2. 未被革除的定时器和回调(clearTimeout(time))3. 闭包 外部函数有权拜访蕴含他的函数的变量
4.dom 的援用
从而,防止内存透露的办法:缩小不必要的全局变量,革除定时器,及时解除援用


sizeof() 函数,实现传入 object,判断所占内存

const data={
    a:111,
    b:'ccc',
    2222:false
}
/*
number:8 字节
string: 每个长度 2 字节
boolean:4 字节
*/
const seen=new WeakSet()
function sizeOfObject(object){if(object===null) return 0
    let bytes=0;
    // 对象里的 key 也占用内存空间
    const properties=Object.keys(object)
    for(let i=0;i<properties.length;i++){const key=properties[i];
        bytes+=calculator(key)

        if(typeof object[key]==='object' &&object[key]!==null){if(seen.has(object[key])){continue}
            seen.add(object[key])
        }
        bytes+=calculator(object[key])

    }
    return bytes
}
function calculator(object){
    const objectType=typeof object
    switch(objectType){
        case 'string':{return object.length*2}
        case 'boolean':{return 4} case 'number':{return 8} case 'object':{if(Array.isArray(object)){return object.map(item=>calculator(item)).reduce((res,current)=>res+current,0)
            }else{return sizeOfObject(object)
            }
        }
        default:{return 0}
    }
}
console.log(sizeOfObject(data))
退出移动版