🅰️ Angular Intermediate

How does Angular handle memory leaks and subscription management?

Answer

Memory leaks in Angular commonly occur from unsubscribed Observables — subscriptions that outlive the component. When the component is destroyed, active subscriptions continue running and hold references to the component, preventing garbage collection. Problem: ngOnInit() { this.router.events.subscribe(e => this.doSomething(e)); // never unsubscribed! } — after component destroy, subscriber still exists. Solutions: (1) async pipe (preferred): template uses {{ data$ | async }} — auto-unsubscribes on destroy. Best for templates; (2) takeUntil pattern: private destroy$ = new Subject<void>(); ngOnInit() { this.dataService.data$.pipe(takeUntil(this.destroy$)).subscribe(data => this.data = data); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); }. takeUntil completes the subscription when destroy$ emits; (3) take(1): auto-completes after first value: this.route.params.pipe(take(1)).subscribe(params => { this.id = params["id"]; }). Use when you only need the value once; (4) Subscription + unsubscribe: private sub = new Subscription(); ngOnInit() { this.sub.add(stream1.subscribe(...)); this.sub.add(stream2.subscribe(...)); } ngOnDestroy() { this.sub.unsubscribe(); }; (5) Angular 16+ takeUntilDestroyed: import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; stream$.pipe(takeUntilDestroyed()) — works outside lifecycle hooks too (in constructors); (6) toSignal(): auto-manages subscription when signal is used in a component.