2016-07-05 4 views
4

このコードをgoogle chromeデベロッパーコンソールで実行した後、 - js-flags = " - expose-gc"を実行した後、JavaScriptの脆弱性が発生する弱点マップは、aがgcである場合にabへの参照を保持し続ける。JavaScript WeakMapはgc'edオブジェクトを参照し続ける

var a = {listener: function(){ console.log('A') }} 
a.b = {listener: function(){ console.log('B') }} 

var map = new WeakMap() 

map.set(a.b, []) 
map.set(a, [a.b.listener]) 

console.log(map) // has both a and a.b 

gc() 
console.log(map) // still have both a and a.b 

a = undefined 
gc() 
console.log(map) // only have a.b: why does still have a reference to a.b? Should'nt be erased? 
+0

これは私のバグのようです。 'gc()'を複数回実行すると持続しますか?もしそうなら、おそらくV8でそれを報告するべきです。 – Bergi

答えて

1

例コードでは、a変数を解放していません。それはスコープから外に出ることのない最上位レベルのvarであり、明示的に参照解除されないので、WeakMapにとどまります。 WeakMap/WeakSetは、コード内でオブジェクトへの参照がなくなるとオブジェクトを解放します。あなたの例では、gc()のコールの1つの後にconsole.log(a)を呼び出した場合でも、aはまだ生きていると思いますか?

だからここWeakSetを示す実施例は、アクションにだとそれはそれへのすべての参照がなくなって一度エントリを削除しますか:https://embed.plnkr.co/cDqi5lFDEbvmjl5S19Wr/

const wset = new WeakSet(); 

// top level static var, should show up in `console.log(wset)` after a run 
let arr = [1]; 
wset.add(arr); 

function test() { 
    let obj = {a:1}; //stack var, should get GCed 
    wset.add(obj); 
} 

test(); 

//if we wanted to get rid of `arr` in `wset`, we could explicitly de-reference it 
//arr = null; 

// when run with devtools console open, `wset` always holds onto `obj` 
// when devtools are closed and then opened after, `wset` has the `arr` entry, 
// but not the `obj` entry, as expected 
console.log(wset); 

注クロームのdevのツールが開かれたことはごみを得ることから、いくつかのオブジェクトを防止することを収集されているため、実際にこれが予想よりも難しくなっています:)

関連する問題