New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于WeakMap的一个问题 #362

Closed
vtxf opened this Issue Mar 30, 2017 · 8 comments

Comments

Projects
None yet
5 participants
@vtxf

vtxf commented Mar 30, 2017

阮老师,你好!
打扰,问您一个问题。

Set 和 Map 数据结构一节讲到的 WeakMap 有这样一段代码:

var wm = new WeakMap();
var element = document.querySelector(".element");

wm.set(element, "Original");
wm.get(element) // "Original"

element.parentNode.removeChild(element);
element = null;
wm.get(element) // undefined

这个里面的这两句:

element = null;
wm.get(element) // undefined

是否可以理解为 wm.get(null),这样的话,貌似就和element没有关系了吧?
我是觉得wm.get(element)并没有办法来检测wm中是否存在没有赋值为null之前的element元素。不知是否有误?

我在chrome控制台上做了如下测试:
image
即使有另外一个变量alias引用了element,最后的结果也还是undefined。

@ruanyf

This comment has been minimized.

Show comment
Hide comment
@ruanyf

ruanyf Mar 30, 2017

Owner

我举的这个例子不好。原意是销毁一个对象,导致它自动在wm之中消失,但是实际上造成了wm.get(null)的效果。

我一时想不出来其他销毁对象的例子,欢迎你帮忙一起想。

Owner

ruanyf commented Mar 30, 2017

我举的这个例子不好。原意是销毁一个对象,导致它自动在wm之中消失,但是实际上造成了wm.get(null)的效果。

我一时想不出来其他销毁对象的例子,欢迎你帮忙一起想。

@ruanyf ruanyf closed this Mar 30, 2017

@hax

This comment has been minimized.

Show comment
Hide comment
@hax

hax Apr 1, 2017

这个示例确实糟糕。。。

实际上 weakmap 就是允许你关联一个对象但不影响 gc 。可以写一个小对象关联一坨数据的例子,使用 weakmap 就允许小对象一旦被删,关联的一坨数据也会被释放掉(否则占用的内存无法回收)。

hax commented Apr 1, 2017

这个示例确实糟糕。。。

实际上 weakmap 就是允许你关联一个对象但不影响 gc 。可以写一个小对象关联一坨数据的例子,使用 weakmap 就允许小对象一旦被删,关联的一坨数据也会被释放掉(否则占用的内存无法回收)。

@zhliner

This comment has been minimized.

Show comment
Hide comment
@zhliner

zhliner Apr 3, 2017

zhliner commented Apr 3, 2017

@hax

This comment has been minimized.

Show comment
Hide comment
@hax

hax Apr 6, 2017

在 node 里可以使用 process.memoryUsage() 来变相测试是否释放(需要占用足够大的内存以便观测)。

hax commented Apr 6, 2017

在 node 里可以使用 process.memoryUsage() 来变相测试是否释放(需要占用足够大的内存以便观测)。

@vtxf

This comment has been minimized.

Show comment
Hide comment
@vtxf

vtxf Apr 7, 2017

之前我一直用chrome的开发者工具测试,虽然那个里面有一个collect garbage的按钮,但是不管用。。
感谢hax提供的process.memoryUsage()这样的方法,我在node中做了如下测试来证明WeakMap的作用:
执行命令 node --expose-gc 后

> global.gc(); // 0 每次查询内存都先执行gc()再memoryUsage(),是为了确保垃圾回收,保证获取的内存使用状态准确
undefined
> process.memoryUsage(); // 1 初始状态,执行gc()和memoryUsage()以后,heapUsed为4M左右
{ rss: 21106688,
  heapTotal: 7376896,
  heapUsed: 4153936,
  external: 9059 }
> var wm = new WeakMap();
undefined
> var b = new Object();
undefined
> global.gc();
undefined
> process.memoryUsage(); // 2 创建WeakMap和对象b以后,heapUsed仍然为4M左右
{ rss: 20537344,
  heapTotal: 9474048,
  heapUsed: 3967272,
  external: 8993 }
> wm.set(b, new Array(5*1024*1024));
WeakMap {}
> global.gc();
undefined
> process.memoryUsage(); // 3 在WeakMap中加入元素b,值为一个5*1024*1024的数组后,heapUsed为45M左右
{ rss: 62652416,
  heapTotal: 51437568,
  heapUsed: 45911664,
  external: 8951 }
> b = null;
null
> global.gc();
undefined
> process.memoryUsage(); // 4 将b置为空以后,heapUsed变成了4M左右,说明WeakMap中的那个长度为5*1024*1024的数组被销毁了
20639744,
  heapTotal: 8425472,
  heapUsed: 3979792,
  external: 8956 }

vtxf commented Apr 7, 2017

之前我一直用chrome的开发者工具测试,虽然那个里面有一个collect garbage的按钮,但是不管用。。
感谢hax提供的process.memoryUsage()这样的方法,我在node中做了如下测试来证明WeakMap的作用:
执行命令 node --expose-gc 后

> global.gc(); // 0 每次查询内存都先执行gc()再memoryUsage(),是为了确保垃圾回收,保证获取的内存使用状态准确
undefined
> process.memoryUsage(); // 1 初始状态,执行gc()和memoryUsage()以后,heapUsed为4M左右
{ rss: 21106688,
  heapTotal: 7376896,
  heapUsed: 4153936,
  external: 9059 }
> var wm = new WeakMap();
undefined
> var b = new Object();
undefined
> global.gc();
undefined
> process.memoryUsage(); // 2 创建WeakMap和对象b以后,heapUsed仍然为4M左右
{ rss: 20537344,
  heapTotal: 9474048,
  heapUsed: 3967272,
  external: 8993 }
> wm.set(b, new Array(5*1024*1024));
WeakMap {}
> global.gc();
undefined
> process.memoryUsage(); // 3 在WeakMap中加入元素b,值为一个5*1024*1024的数组后,heapUsed为45M左右
{ rss: 62652416,
  heapTotal: 51437568,
  heapUsed: 45911664,
  external: 8951 }
> b = null;
null
> global.gc();
undefined
> process.memoryUsage(); // 4 将b置为空以后,heapUsed变成了4M左右,说明WeakMap中的那个长度为5*1024*1024的数组被销毁了
20639744,
  heapTotal: 8425472,
  heapUsed: 3979792,
  external: 8956 }
@ruanyf

This comment has been minimized.

Show comment
Hide comment
@ruanyf

ruanyf Apr 7, 2017

Owner

这个例子比我原先那个好多了,我要把它更新到书里。

太感谢大家了。:)

Owner

ruanyf commented Apr 7, 2017

这个例子比我原先那个好多了,我要把它更新到书里。

太感谢大家了。:)

@foxdyor

This comment has been minimized.

Show comment
Hide comment
@foxdyor

foxdyor Apr 26, 2017

阮老师,你好!发现在 http://es6.ruanyifeng.com/#docs/set-map 链接里的vtxf例子代码里有个笔误,const b = new Object(); 应为 var b = new Object(); 不然后边无法执行 b = null;谢谢

foxdyor commented Apr 26, 2017

阮老师,你好!发现在 http://es6.ruanyifeng.com/#docs/set-map 链接里的vtxf例子代码里有个笔误,const b = new Object(); 应为 var b = new Object(); 不然后边无法执行 b = null;谢谢

@ruanyf

This comment has been minimized.

Show comment
Hide comment
@ruanyf

ruanyf Apr 26, 2017

Owner

@foxdyor 谢谢指出,已经改成let了。

Owner

ruanyf commented Apr 26, 2017

@foxdyor 谢谢指出,已经改成let了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment