2016-07-05 1 views
4

Je rencontre des faiblesses Javascript, après avoir essayé ce code dans google chrome developer console, en cours d'exécution avec --js-flags = "- -exposer-gc", je ne comprends pas pourquoi la weakmap garde une référence à ab si a est gc'ed.JavaScript WeakMap continuer à référencer les objets 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

Cela ressemble à un bug pour moi. Cela persiste-t-il si vous 'gc()' plusieurs fois? Si oui, vous devriez probablement le signaler avec V8. – Bergi

Répondre

1

Dans votre exemple de code, vous n'êtes pas libérer votre variable a. C'est un var niveau supérieur qui ne sort jamais de la portée et ne reçoit jamais explicitement de référence, donc il reste dans la WeakMap. WeakMap/WeakSet libère des objets une fois qu'il n'y a plus de références dans votre code. Dans votre exemple, si vous console.log(a) après l'un de vos gc() appels, vous attendez toujours a d'être en vie, non?

Alors, voici un exemple de travail montrant WeakSet dans l'action et la façon dont il va supprimer une entrée, une fois toutes les références à celui-ci sont partis: 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); 

Notez que comportant des outils de dev Chrome ouvert empêche certains objets de l'obtention des ordures collecté, ce qui rend la voir en action plus difficile que prévu :)