4

I'm trying to understand how to avoid memory leaks in AngularJS. There seems to be almost no documentation about what to clean up, which is as one would expect if garbage collection were perfect and omniscient. However, my reading indicates that it's easy to leave bound DOM elements which prevent garbage collection, this StackOverflow answer says that we must manually unbind any bindings set in directives, and on a smaller scale, clean up $timeouts as well. I came across this article, which instructs me to look for "detached" DOM elements.

Using just the sample $modal code from the AngularJS UI site, I find numerous sizable detached elements after opening and closing the modal dialog. It doesn't seem to grow with repeated clicking, but if I have many dialogs, each one leaves its footprint seemingly forever. I tried setting modalInstance = null after close, but that didn't accomplish anything.

Are detached elements truly bad? If so, how should the AngularJS UI sample modal code be modified to eliminate these?

More importantly, are there any simple, clear, instructions for what specifically to clean up when using AngularJS? It's nice that they provide an $on.$destroy function, but I can't find any clear instructions indicating what I'm responsible for cleaning up, or how to do it.

Community
  • 1
  • 1
Dev93
  • 668
  • 1
  • 6
  • 18

2 Answers2

0

I am afraid that detached elements is more complex problem which leads to uncontrolled memory leaking. I researched a way to remove this problem for me. And that is that the native ui.bootstrap modal behaviour can be changed via custom $modal factory which prevents destroying and reinstantiating of a dialog. So the $modal dialog becomes a singleton.

I've shared my try of this solution at github: https://github.com/dhilt/angular-bootstrap-modal-singleton. And I use it in projects I working on.

dhilt
  • 18,707
  • 8
  • 70
  • 85
  • Thanks for the pointer! I'm (a little) surprised that you're saying this basic building block has fundamental internal problems. I hope the team over there looks at your solution. However, my question was more general: I was looking for overall guidance on AngularJS memory leak protection and best/expected practices. – Dev93 Feb 08 '15 at 01:03
  • Something like 1) manual unbind $rootScope.$on listeners each time the $scope is destroyed, 2) manual disposing of external plugins, 3) a transclude linking function transcludeFn(scope, cloneLinkingFn(clone)) execution must be accompanied by the clone manual removing on the scope destroying (clone.remove()) etc Yes, it would be very helpfull to have such list... PS they have fixed their $modal leakages in ui.bootstrap 0.12.0 – dhilt Feb 14 '15 at 09:23
0

This is a bug from angular-ui:

This is due to us re-using the modal scope. Each time the scope is re-used and attached on a different element, watchers are added onto the scope

here the fix

Marwen Trabelsi
  • 4,167
  • 8
  • 39
  • 80