先看一个例子强引用和弱引用之间有什么区别呢?

先看一个例子

let obj = { name: 'toto' }
// { name: 'toto' }这个对象能够被读取到,因为obj这个变量名有对它的引用
// 将引用覆盖掉
obj = null
// 这个对象将会被从内存中移除,因为我们已经失去了对它所有的引用

再来看另外一个例子

let obj = { name: 'toto' }
let arr = [ obj ]
obj = null

在这个例子中,对象{name:'toto'}不会被从内存中移除,因为数组arr保存了对它的引用

强引用和弱引用有什么区别?

事实上,javascript 中的大多数变量都持有对对象的强引用。例如,上面的数组包含对对象 {name:’toto’}

的强引用

如果变量持有对对象的强引用,则该对象不会被垃圾回收,但如果变量只持有对该对象的弱引用,则该对象将被垃圾回收

一些变量类型对对象有弱引用,Weakmap就是这种情况

弱图

weakmap 是一种额外的数据存储,它允许我们扩展或封装来自外部(第三方库)的对象,而无需推断垃圾收集或智能创建缓存函数的能力。

看不懂的别着急,我会在比较map和weakmap之前解释并展示它的含义。

Map和Weakmap的比较

使用map,对象会占用内存,可能不会被垃圾回收。 Map 是对对象的强引用

let obj = { name: 'toto' }
let mapObj = new Map()
mapObj.set(obj, 'any value')
obj = null
mapObj.size() // 1

 

Weakmap 完全不同,它不会阻止关键对象的垃圾回收

第一条规则是weakmap只接受对象作为键,第二条规则是它只持有对象的弱引用。

let obj = { name: 'toto' }
let weakmapObj = new WeakMap()
weakmapObj.set(obj, 'any value')
obj = null
weakmapObj .size() // 0

对象被垃圾收集器删除,因为weakmap只有一个对对象{ name: ‘toto’ }的弱引用,它不再有强引用。 (只有变量 obj 有持有引用)

什么时候应该使用 Wea​​kmap?

如您所见,Weakmap 可以在任何地方使用

注册函数

const cache = new WeakMap() 
const process = function (obj) { 
    // 如果输入的值不在缓存器中
    if (!cache.has(obj)) { 
        // 想象一个函数需要很大的内存或者资源
        // 当输入相同时,我们不想重复执行bigOperation函数
        const result = bigOperation(obj) 
        // 所以此时执行一次函数并将它的结果存入缓存中
        cache.set(obj, result) 
    } 
    return cache.get(obj) 
} 
let obj = { /* any object */ } 
// 第一次我们没有这个输入作为缓存,所以在第二次的时候我们才不需要执行这个函数,
const firstResult = process(obj) 
// 只需要从缓存中取出结果
const secondeResult = process(obj) 
// 源对象将被从weakmap中移除
obj = null 

使用map,这个缓冲函数应该将obj对象保存在内存中。

但这会导致内存泄漏!

当我们保留对不再使用的对象的引用时会发生内存泄漏,因此如果您不再使用该对象,请删除对其的所有变量引用。

我们不应该在使用weakmap时使用.keys() / .values() /.entries(),因为我们不知道垃圾收集器什么时候会移除对象。

最后一个例子

动态无泄漏内存的访问计数器

// 访问计数器
let visitsCountMap = new WeakMap()
// 增加访问计数
function countUser(user) {
  const count = visitsCountMap.get(user) || 0
  visitsCountMap.set(user, count + 1)
}
let toto = { name: "toto" }
countUser(toto) // 计算访问次数
// 将toto对象从内存中移除
toto = null

© 版权声明
THE END
喜欢就支持一下吧
点赞108 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片