2013-07-09 11 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が存在しない場合に、オブジェクトがアクセス不能になった場合、動的ではない「リーク」メモリリソースを行う方法で、オブジェクトと状態を関連付けるためのメカニズムを提供することを意図しています実装のガーベッジ・コレクション・メカニズムによるリソース・レクラメーションの対象となります。 weakMap.set(domElement, data);

を使用すると、DOM要素を持っており、それにいくつかのデータを関連付け、そのため WeakMapを使用してみたいと思います。 DOM要素が削除されると、弱いマップのエントリも削除されます。

一方、弱点マップの外側に他の参照がないため、DOM要素が存在する限り、データを削除したくない場合があります。

とは別に'fish cans'はプリミティブ型であり、ガベージコレクションの対象ではありません。

11

なぜ'fish cans'の値はまだアクセス可能で、ガベージコレクションされていませんか?変数rubbishはもはやそれを参照しておらず、キーから'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

私もこれを理解しようとしています。私は段落のように言ったと思う:原因WeakMapへ

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. 

は、キーを取得する方法がありません、あなたはそれ以上その「値」を取得する方法がありません。

変数キーが参照を失ったにもかかわらず、has()、entries()があるためMap()を使用すると、 "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;と同様に繰り返されます。一般に、任意の再割り当ては望ましい変更になります。

関連する問題