Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit f552f25

Browse files
IgorMinartbosch
authored andcommitted
fix(Scope): aggressively clean up scope on $destroy to minimize leaks
Due to a known V8 memory leak[1] we need to perform extra cleanup to make it easier for GC to collect this scope object. The theory is that the V8 leaks are due to inline caches which are caches built on the fly to speed up property access for javascript objects. By cleaning the scope object and removing all properties, we clean up ICs as well and so no leaks occur. I was able to manually verify that this fixes the problem for the following example app: http://plnkr.co/edit/FrSw6SCEVODk02Ljo8se?p=preview Given the nature of the problem I'm not 100% sure that this will work around the V8 problem in scenarios common for Angular apps, but I guess it's better than nothing. [1] V8 bug: https://code.google.com/p/v8/issues/detail?id=2073 Closes #6794 Closes #6856
1 parent ec8e395 commit f552f25

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

src/ng/rootScope.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -731,15 +731,26 @@ function $RootScopeProvider(){
731731

732732
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
733733

734+
// sever all the references to parent scopes (after this cleanup, the current scope should
735+
// not be retained by any of our references and should be eligible for garbage collection)
734736
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
735737
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
736738
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
737739
if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
738740

739-
// This is bogus code that works around Chrome's GC leak
740-
// see: https://github.com/angular/angular.js/issues/1313#issuecomment-10378451
741-
this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead =
742-
this.$$childTail = null;
741+
// This is bogus code that works around V8's memory leak coming from ICs
742+
// see: https://code.google.com/p/v8/issues/detail?id=2073#c26
743+
//
744+
// for more info also see:
745+
// - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909
746+
// - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451
747+
for (var prop in this) {
748+
if (hasOwnProperty.call(this, prop)) {
749+
this[prop] = null;
750+
}
751+
}
752+
// recreate the $$destroyed flag
753+
this.$$destroyed = true;
743754
},
744755

745756
/**

0 commit comments

Comments
 (0)