-
Notifications
You must be signed in to change notification settings - Fork 27.5k
decrementListenerCount: TypeError: Cannot read property '$destroy' of null #6897
Comments
Suspect: f552f25 |
BTW it works with 1.2.15 and also I'm pretty sure that it worked with 1.3 at some point. |
Does it happen in FF and Chrome (or other browsers)? |
Happens on both Firefox 28 and Chromium 33.0.1750.152 (OS is Linux). |
Can you try with v1.3.0-build.2531+sha.ec8e395? If it doesn't happen there it's 50% in the commit I referenced. It'll also be helpful if you had a minimal reproduction. |
looking into this |
Ok, was able to reproduce this, there are a few small issues here:
|
When trying to register an event on a child scope of an already destroyed scope, make this a noop When trying to deregister an event on a child scope of an already destroyed scope, make this a noop Closes angular#6897
Just curious, shouldn't you fix the cause and not the symptoms here? I mean it looks like attempt to destroy a scope twice is the real bug here and not the exception which is just a symptom. Anyway, I won't be able to prepare a minimal test case for this, best I can do is try different builds to help you bisect if needed. |
@ppawel a scope cannot be destroyed twice, the first check that is done on the The fact that you are seeing a scope that is destroyed, does not mean that this is the scope that we are attempting to destroy twice, but the fact that when some of the previous operations is performed on a child scope, it needs to modify the parent hierarchy. |
Destroying the listener properties cases many issues when any of these operations is being performed on a destroyed scope or a child scope * Registering a new event * Deregistering an existing event * Destroying an insolated child scope with a destroyed parent * Sending an `$emit` from a child scope with a destroyed parent Closes angular#6897
Add several checks on the methods that handle listeners so they are able to handle destroyed scopes that now do not have the references to the `$$listeners` and `$$listenersCount` when destroyed Closes angular#6897
@jeffbcross this is related to the mem leak issue I'm dealing with, so I'll take over the ownership of this one. |
ok, I reverted the commit that introduced this. we still need some solution to deal with the V8 bug that the reverted commit worked around, but we need to do implement it better. @lgalfaso I'm trying other strategies, but will keep your PR in mind in case I don't come up with another workaround. |
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. V8 leaks are due to strong references from optimized code (fixed in M34) and inline caches (fix in works). Inline caches are caches that the virtual machine builds on the fly to speed up property access for javascript objects. These caches contain strong references to objects so under certain conditions this can create a leak. The reason why these leaks are extra bad for Scope instances is that scopes hold on to ton of stuff, so when a single scope leaks, it makes a ton of other stuff leak. This change removes references to objects that might be holding other big objects. This means that even if the destroyed scope leaks, the child scopes should not leak because we are not explicitly holding onto them. Additionally in theory we should also help make the current scope eligible for GC by changing properties of the current Scope object. I was able to manually verify that this fixes the problem for the following example app: http://plnkr.co/edit/FrSw6SCEVODk02Ljo8se 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. This is a second attempt to enhance the cleanup, the first one failed and was reverted because it was too aggressive and caused problems for existing apps. See: angular#6897 [1] V8 bug: https://code.google.com/p/v8/issues/detail?id=2073 Closes angular#6794 Closes angular#6856
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. V8 leaks are due to strong references from optimized code (fixed in M34) and inline caches (fix in works). Inline caches are caches that the virtual machine builds on the fly to speed up property access for javascript objects. These caches contain strong references to objects so under certain conditions this can create a leak. The reason why these leaks are extra bad for Scope instances is that scopes hold on to ton of stuff, so when a single scope leaks, it makes a ton of other stuff leak. This change removes references to objects that might be holding other big objects. This means that even if the destroyed scope leaks, the child scopes should not leak because we are not explicitly holding onto them. Additionally in theory we should also help make the current scope eligible for GC by changing properties of the current Scope object. I was able to manually verify that this fixes the problem for the following example app: http://plnkr.co/edit/FrSw6SCEVODk02Ljo8se 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. This is a second attempt to enhance the cleanup, the first one failed and was reverted because it was too aggressive and caused problems for existing apps. See: angular#6897 [1] V8 bug: https://code.google.com/p/v8/issues/detail?id=2073 Closes angular#6794 Closes angular#6856
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. V8 leaks are due to strong references from optimized code (fixed in M34) and inline caches (fix in works). Inline caches are caches that the virtual machine builds on the fly to speed up property access for javascript objects. These caches contain strong references to objects so under certain conditions this can create a leak. The reason why these leaks are extra bad for Scope instances is that scopes hold on to ton of stuff, so when a single scope leaks, it makes a ton of other stuff leak. This change removes references to objects that might be holding other big objects. This means that even if the destroyed scope leaks, the child scopes should not leak because we are not explicitly holding onto them. Additionally in theory we should also help make the current scope eligible for GC by changing properties of the current Scope object. I was able to manually verify that this fixes the problem for the following example app: http://plnkr.co/edit/FrSw6SCEVODk02Ljo8se 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. This is a second attempt to enhance the cleanup, the first one failed and was reverted because it was too aggressive and caused problems for existing apps. See: #6897 [1] V8 bug: https://code.google.com/p/v8/issues/detail?id=2073 Closes #6794 Closes #6856 Closes #6968
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. V8 leaks are due to strong references from optimized code (fixed in M34) and inline caches (fix in works). Inline caches are caches that the virtual machine builds on the fly to speed up property access for javascript objects. These caches contain strong references to objects so under certain conditions this can create a leak. The reason why these leaks are extra bad for Scope instances is that scopes hold on to ton of stuff, so when a single scope leaks, it makes a ton of other stuff leak. This change removes references to objects that might be holding other big objects. This means that even if the destroyed scope leaks, the child scopes should not leak because we are not explicitly holding onto them. Additionally in theory we should also help make the current scope eligible for GC by changing properties of the current Scope object. I was able to manually verify that this fixes the problem for the following example app: http://plnkr.co/edit/FrSw6SCEVODk02Ljo8se 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. This is a second attempt to enhance the cleanup, the first one failed and was reverted because it was too aggressive and caused problems for existing apps. See: #6897 [1] V8 bug: https://code.google.com/p/v8/issues/detail?id=2073 Closes #6794 Closes #6856 Closes #6968
Just to confirm - it works for me now. |
I see this message in v1.3.0-build.3024+sha.60c13a1
|
I am still seeing this issue when doing like these:
here is the error message: TypeError: Cannot read property '$destroy' of undefined
at Object.IonicModule.controller.self.createHeaderBar.headerBarInstance.removeItem (ionic.bundle.js:47770)
at Object.IonicModule.controller.self.createHeaderBar.headerBarInstance.setItem (ionic.bundle.js:47746)
at ionic.bundle.js:47890
at forEach (ionic.bundle.js:9150)
at IonicModule.controller.self.update (ionic.bundle.js:47889)
at IonicModule.controller.self.beforeEnter (ionic.bundle.js:48315)
at IonicModule.controller.self.beforeEnter (ionic.bundle.js:50259)
at Scope.$get.Scope.$emit (ionic.bundle.js:23474)
at Object.IonicModule.factory.ionicViewSwitcher.create.switcher.emit (ionic.bundle.js:46814)
at Object.IonicModule.factory.ionicViewSwitcher.create.switcher.transition (ionic.bundle.js:46672) |
With AngularJS v1.3.0-build.2533+sha.ff5cf73 I get the following in my application. It occurs during navigation, it looks as if Angular tries to destroy one of the scopes in my application twice.
Scope looks like this at this point:
The text was updated successfully, but these errors were encountered: