5

Mam pytanie dotyczące wycieku pamięci w pamięci JavaScript. Używam Chrome 28.0.1500.71 na OS X 10.8.4.Wyciek z powodu zamknięcia zapory w języku JavaScript

Poniższy kod nigdy nie zwalnia miejsca, które było w posiadaniu me i nie mam pojęcia, dlaczego.

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 
}; 
MyClass.prototype.destroy = function() { 
    delete this.do_thing; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 

// the MyClass object formerly known as 'me' is still allocated here 
// (as evidenced by Chrome's heap profiler) 

Chrome wydaje się utrzymanie obiektu utworzonego przez ekspresję new MyClass() (obiektu, który me wskazał przed ustawiony null) w pamięci, ponieważ odwołuje się self w zaproszeniu do me.do_thing(). Jednak pomyślałem, że wywołanie destroy(), które wyłączy me.do_thing, wyrzuci zmienne w zakresie konstruktora (self w wywołaniu new MyClass()).

Próbowałem również użyć funkcji Underscore.JS w _.bind, ale uruchomiono ten sam nierozwiązany problem opisany tutaj: Instances referenced by 'bound_this' only are not garbage collected.

+0

Proszę dokładnie rozróżnić "zmienną globalną" ja' "i" obiekt 'MyClass'". Zmienna na pewno pozostanie w pamięci, ale to nie jest problem (a jeśli tak, to możesz ją usunąć z 'okna', zobacz odpowiedź simonleunga). Czy Chrome wskazuje, że obiekt 'MyClass' nadal żyje? – delnan

+0

Fair point; jest to obiekt 'MyClass', do którego * odwoływał się * me, który nigdy nie zostaje zwolniony. Zaktualizowałem treść mojego pytania, aby było to jaśniejsze. – soney

+1

Wygląda na to, że jest błąd w V8, otworzyłem problem z tym: https://code.google.com/p/v8/issues/detail?id=2791 –

Odpowiedz

0

Ja nadal jest właściwością obiektu window, nawet jeśli ustawisz go na wartość null. Tak więc "ja" wciąż jest w pamięci.

myślę, że może to pomóc:

window.me = new MyClass(); 
me.do_thing(); 
delete window.me; 
+0

Ten fragment nadal pozostawia obiekt 'MyClass' przydzielony w moja przeglądarka. – soney

1

Nie wiem, dlaczego to nie śmieci zbierane, ale dodanie zniszczyć metody instancji zamiast prototypu i ustawienie self null, to najwyraźniej działa :

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 

    this.destroy = function() { 
     delete this.do_thing; 
     self = null; 
    }; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 
+0

Interesujące, chociaż wciąż jestem ciekawy, dlaczego 'self' musi być ręcznie usuwany – soney

+0

@soney, wydaje się, że ma to coś wspólnego z przypisaniem' self.x' w linii 'self.x ++'. Jeśli zmienisz tę linię na 'return self.x', to również zostaną zebrane śmieci. – basilikum

0

MyClass jest zmienną globalną. Jest to również właściwość obiektu okna w środowisku przeglądarki. To nie jest śmiecie, więc nie zostanie zebrane.

+0

Podczas gdy funkcja 'MyClass' zajmuje przestrzeń, odwołuję się do obiektu utworzonego przez wyrażenie' new MyClass() '. Po ustawieniu 'me' na wartość null, nie powinno to mieć więcej odniesień do niego i powinno zostać zebrane. – soney

+0

obiekt zostanie pobrany przez gc, ale nie natychmiast. Spróbuj odświeżyć i wygenerować nową migawkę sterty, nie zobaczysz żadnego obiektu MyClass. – simonleung

0

Wygląda jak błąd. Btw me.destroy() nie jest konieczne. Powinien zostać usunięty bez tego.

Powiązane problemy