先看一个例子

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

weakmap是一个额外的数据存储,它可以让我们从外部(第三方库)扩展或者封装一个对象,而不需要进行垃圾回收的推断,或者能够智能的创建一个缓存函数。

不用担心看不明白,在比较mapweakmap之前我将解释并展示它的含义。

Map和Weakmap的比较

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

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

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

第一条规则,weakmap只接受object作为key,第二条规则是它只保存对对象的弱引用。

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

对象被垃圾回收器删除,因为weakmap在对象{ name: ‘toto’ }上只有弱引用,而这个对象已经没有强引用了。(只有变量obj有保持引用)

何时使用Weakmap?

正如你所看到的,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

最新文章

  1. xcode调整debug,release模式
  2. 为 Exchange 服务器编写自定义的反垃圾插件
  3. canvas对象arc函数的使用-遁地龙卷风
  4. 动态内存分配导致Javascript性能的问题
  5. DropMaster
  6. C语言二重指针与malloc
  7. SpringMVC注解@RequestParam(转)
  8. HTTP 错误 500.19- Internal Server Error 错误解决方法 分类: Windows服务器配置 2015-01-08 20:16 131人阅读 评论(0) 收藏
  9. mvc+ef5+easyui实例(1)
  10. XCODE 控件连接(关联)不上变量 怎么解决
  11. operator[] 和 insert
  12. Python小代码_3_购物车
  13. 解决 c3p0报错 Establishing SSL connection without server's identity verification is not recommended
  14. Windows下android模拟器环境搭建
  15. java任务调度框架
  16. CentOS 6.8 安装Tomcat7
  17. 在android程序中打开另一个应用程序
  18. 安装selenium python
  19. python实现进制之间的转换
  20. Java - 避免使用finalizer

热门文章

  1. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02
  2. Docker的简介
  3. LibreOffice(开源免费办公软件)
  4. 新手入门C语言第七章:C判断
  5. 1903021116-吉琛- JAVA第二周作业—Java程序编写
  6. 记一次docker安装成功,启动失败的原因
  7. android软件简约记账app开发day04-记账页面条目的代码书写
  8. docker入门_image、container相关命令
  9. 新的 css 子选择器
  10. python基础练习题(题目 字母识词)