2013-07-09 43 views
9

ECMAScript 6引入了弱地图,可用Node.JS v0.11.3和--harmony标志提供。考虑以下。了解弱地图

let weakMap = WeakMap(); 
let key = []; 
let rubbish = 'fish cans'; 

weakMap.set(key, rubbish); 
rubbish = 'empty bottle'; 

// Prints "fish cans" 
console.log(weakMap.get(key)); 

我的印象是,弱的地图,从关键值的参考是下,这样,如果该值的唯一引用是关键,那么值不再被访问。

为什么然后值'fish cans'仍然可以访问,而不是垃圾收集?变量rubbish不再引用它,并且从key'fish cans'的引用是,即从垃圾收集器的观点来看是不存在的。我错过了什么?

+1

我猜测值* still *可以被访问,只是因为垃圾人没有通过街道。换句话说,也许如果你尝试了一段时间后不起作用? –

+0

一种方法来检查是否是这种情况将运行一个虐待循环的分配,其中的引擎将被迫GC填补。如果它仍然存在,那么有东西持有它。 –

回答

16

的脆弱的部分是关键,而不是价值。从当前草案:

WeakMap旨在提供用于如果,在不存在WeakMap的,对象否则变得不可访问动态状态与在不“泄漏”的存储器资源一种方式的对象关联提供了一种机制并受实施的垃圾收集机制的资源回收。

假设您有一个DOM元素,并且想要将一些数据与它关联起来,并且使用WeakMap表示:weakMap.set(domElement, data);。当DOM元素被删除时,弱地图中的条目也被删除。

另一方面,只要DOM元素存在,您不希望数据被删除,只是因为在弱映射外没有其他引用。

除此之外,'fish cans'是一种原始类型,因此不受垃圾回收限制。

11

为什么然后值'fish cans'仍然可以访问,而不是垃圾收集?可变垃圾不再引用它,并且从关键到'fish cans'的引用是弱的,即从垃圾收集器的观点来看是不存在的。我错过了什么?

变量rubbish从来不是需要引用它的那个。只要密钥没有被收集,从键到值的关联(引用)仍然存在。 GC无法看到的弱引用是从映射到键/值对(使映射可枚举的映射)的引用。然而,你的key仍然存在,你可以得到你保存它在地图中的每个值:

var map = WeakMap(), 
    key = []; 

map.set(key, 'fish cans'); 
console.log(map.get(key)); // Prints "fish cans" 

为了演示的弱点,你必须使用以下命令:

var map = WeakMap(), 
    key = []; 

map.set(key, 'fish cans'); 
// map.size == 1 
key = null; 
// map.size == 0 - the fish cans got garbage-collected together with the key 
map.get(???) // impossible now 
0

我想了解这一点。我认为该段落如下所示:

var key={a:1}; 
var wm=new WeakMap(); 


wm.set(key,"value"); 
wm.get(key); //you can get "value"; 

key=undefined; 
console.log(wm.get(key));//error.original key have no longer existed. so "value" is not longer existed as well. 

由于WeakMap无法检索密钥,因此无法再获取该“值”。如果我们使用Map(),由于有keys(),entries(),尽管变量key丢失了引用,“value”仍然可以被检索到。

var key={a:1}; 
var m=new Map(); 


m.set(key,"value"); 
console.log(m.keys().next());; //you can get "value"; 

key=undefined; 
console.log(m.get(m.keys().next().value));//you can get "value"; 

结论:

如果WeakMap对象键已经失去了它的参考,该键和值将被垃圾收集以及(因为在逻辑上不可访问)。这样可以防止内存泄漏。

如果地图的对象键已丢失其引用,则此键和值将一直可用,直到您删除或清除为止。因此,你需要发展

过程中要注意内存泄漏只要找到一个大概了解weakmap及其使用情况的链接: http://ilikekillnerds.com/2015/02/what-are-weakmaps-in-es6/

0

我加入这个答案地址/澄清以下一点:

变量'rubbish'的初始值从未发生变异;您在rubbish = 'empty bottle';上完成的所有工作就是将别名rubbish关联到不同的值。因此,即使执行了rubbish = 'empty bottle';之后,带有键'key'的weakMap条目仍具有与其相关的值,该值与原始值rubbish相关。

然后使价值失去与键的关联,您应该的关键变量的变化(如已经在@ BERGI的答案说明)。

请注意key.push("whatever");不等于更改。然而,key = [];再次重复将会和key = null;一样好。一般来说,任何重新分配都会达到所需的更改。