Angular
  • Angular learning
  • Angular
    • Change Detection
      • Angular Change Detection Strategies
      • Understanding Change Detection Strategy in Angular
    • Angular Components Overview
      • Lifecycle hooks
      • View encapsulation
    • Text interpolation
    • Pipes
    • ARIA
    • Event binding
    • Directives
    • Dependency injection in Angular
    • Difference between Template-Driven and Reactive Forms
    • Guards
    • Resolvers
      • Resolver example
  • Memory management in Angular applications
  • Renderer2
  • Angular test
    • Testing
      • The different types of tests
      • Some testing best practices
      • Angular Service Testing in Depth
        • About Jasmine
        • Jasmine - Test suites
        • Implementation of First Jasmine Specfication
        • spyOn() & jasmine.createSpyObj()
        • beforeEach()
        • Testing services
        • Disabled and Focused Tests
        • flush
        • HttpTestingController
        • Sample code
      • Angular Component Testing in Depth
        • Intro to Angular Component testing
        • DOM interaction
        • Trigger Change Detection
        • Test Card List Test Suite Conclusion
        • Window.requestAnimationFrame()
        • Asynchronous Work (Jasmine)
        • Cooperative asynchronous JavaScript: Timeouts and intervals
        • FakeAsync - Asynchronous Work (Jasmine) part 2
        • tick()
        • Sample codes
      • Testing Promised-based code-intro Microtasks
        • Microtasks
        • Micro-tasks within an event loop (Summary)
        • Macro-tasks within an event loop (Summary)
        • Test promised Microtasks (code)
      • Using fakeAsync to test Async Observables
      • Cypress.io
        • Create our first e2e test
      • Angular CLI code coverage and deployment in prod mode.
      • Travis CI
  • Angular best practices
    • Angular best practices
      • Security
      • Accessibility in Angular
      • Keeping your Angular projects up-to-date
    • Bootstrapping an Angular Application
      • Understanding the File Structure
      • Bootstrapping Providers
    • Components in Angular
      • Creating Components
      • Application Structure with Components
        • Accessing Child Components from Template
        • Using Two-Way Data Binding
        • Responding to Component Events
        • Passing Data into a Component
      • Projection
      • Structuring Applications with Components
      • Using Other Components
  • Reactive extensions
    • RxJS
      • RxJS Operators
      • of
      • Observable
      • async pipe (Angular)
      • Interval
      • fromEvent
      • Pipe
      • Map
      • Tap
      • ShareReplay
      • Concat
      • ConcatMap
      • Merge
      • MergeMap
      • ExhaustMap
      • fromEvent
      • DebounceTime
        • Type Ahead
      • Distinct Until Changed
      • SwitchMap
      • CatchError
      • Finalize
      • RetryWhen
      • DelayWhen
      • ForkJoin
      • First
      • Interview Questions
      • Zip
  • NgRx
    • What's NgRx
      • Actions
      • Reducers
      • Selectors
      • 🙅‍♂️Authentication guard with NgRX
      • @ngrx/effects
        • Side-Effect refresh survivor
  • Interview Q&A
    • Angular Unit Testing Interview Questions
    • Angular Questions And Answers
  • Angular Advanced
    • Setting up our environment
      • Understanding Accessors (TS)
      • The host & ::ng-deep Pseudo Selector
Powered by GitBook
On this page
  • When does Angular release a component from memory?
  • Strategies to prevent leaks

Was this helpful?

Memory management in Angular applications

PreviousResolver exampleNextRenderer2

Last updated 4 years ago

Was this helpful?

Javascript is a high level language that doesn’t include memory management features. Memory gets automatically allocated when the program creates an object or released when the program no longer needs it. In order to deallocate that memory it relies in the to decide when to release an object from memory. Basically what the GC does is look for values that do not have any references on them (they do not exist anymore from the program point of view) so they get released from memory.

Most of the time this recollection of resources happens without any issues but there are situations when the GC cannot decide if an object should be released or not. Then the memory footprint of a program might grow unexpectedly and produce performance problems or crashes.

Is in the hand of the developer then to prevent and solve this issues.

When does Angular release a component from memory?

One common pattern in angular applications is to use ng-if to manage the visibility of parts of the application. When passed a falsy value, ng-if will remove its child element and will also call the $destroy event in its child scopes.

Also the ng-view directive of the angular router will replace the html elements of the transcluded contents when changing the route and also call the $destroy on the transcluded scope.

The $destroy function nullifies the scope reference to the parent scope, severing the tree connection downwards. As that scope do not longer has any references on it, it will be marked as collectible and released eventually by the GC.

Event listeners

The most likely culprit of a memory leak in Angular is adding an event listener to a DOM object. If you forget to remove the listener on the $destroy event of your directive, it will hold a reference to a DOM node even if it is removed from the document. The DOM tree will then become a “Detached DOM tree” and will leak.

Modern JS engines are able to figure most of this situations for you and remove the listeners, but more complex tree hierarchies can challenge even the best GC.

Subscriptions

If you use a library that exposes a subscription interface (Redux, RxJS, etc.) you have to remember to dispose the subscriptions on component removal.

Strategies to prevent leaks

  • Nullify all references to models in a component on the component $destroy phase

  • Try to remove all circular dependencies by using yet another layer of indirection

  • Create a this.state object to manage the instance state in a place for easier nullification

  • Dispose subscriptions

  • Examine third party software and decide to use it or not also based on memory problems or contribute with PRs

Garbage Collector