Memory Management in TypeScript: How the Garbage Collector Works

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Memory and Garbage Collector in TypeScript: What's Behind the Scenes?

\n\n

Imagine you are building a house. You buy bricks, cement, rebar — but if you don't clean up the construction debris, the site will soon turn into a dump. The same thing happens in your TypeScript code. You create objects, arrays, closures — and if you don't free up memory in time, the application starts to slow down, and then crashes with an Out of Memory error.

\n\n

In this article, we will break down how memory management in TypeScript works and its main tool — the garbage collector. You will learn what mechanisms are behind memory deallocation, how to avoid leaks, and why your code can "eat" megabytes even after you stop using it.

\n\n

Let's go!

\n\n

How Does TypeScript Manage Memory? The Basics

\n\n

Let's start with an important point: TypeScript is not a separate language, but a superset of JavaScript. This means that memory and the garbage collector in TypeScript work exactly the same as in JavaScript. TypeScript does not add new memory management mechanisms, but it gives us tools (types, interfaces) to write safer code.

\n\n

In JavaScript, memory is divided into two main areas:

\n\n
    \n
  • Stack — stores primitives (numbers, strings, booleans) and references to objects. It is automatically freed when a function exits.
  • \n
  • Heap — stores objects, arrays, functions. This is where the garbage collector works.
  • \n
\n\n

When you write:

\n\n
const user = { name: 'Alice', age: 30 };
\n\n

The variable user is stored on the stack and contains a reference to the object in the heap. As long as there is a reference, the object is alive. Once the reference disappears, the object becomes "garbage".

\n\n

Garbage Collector in TypeScript: How Does It Work?

\n\n

The garbage collector (GC) is an automatic process that finds objects that are no longer referenced and frees the memory they occupy. Modern engines (V8 in Chrome, SpiderMonkey in Firefox) use complex algorithms, but the foundation is the Mark-and-Sweep algorithm.

\n\n

How it works:

\n\n
    \n
  1. The GC starts from "roots" — global objects, local variables in executing functions.
  2. \n
  3. It traverses all references from the roots and marks every reachable object.
  4. \n
  5. All unmarked objects are considered garbage and are removed.
  6. \n
\n\n

Sounds simple, but in practice there are nuances. For example, circular references:

\n\n
function createCycle() {\n    const obj1: any = {};\n    const obj2: any = {};\n    obj1.ref = obj2;\n    obj2.ref = obj1;\n    return 'done';\n}
\n\n

In the past, such structures led to leaks, but modern garbage collectors handle cycles perfectly — the main thing is that both objects are unreachable from the roots.

\n\n

Typical Memory Leaks in TypeScript Applications

\n\n

Even with a smart garbage collector, you can "step on a rake". Here are the most common scenarios that lead to memory leaks in TypeScript:

\n\n

1. Forgotten Timers and Event Handlers

\n\n

One of the most common causes. You subscribed to an event but forgot to unsubscribe:

\n\n
class TimerComponent {\n    private intervalId: number;\n\n    start() {\n        this.intervalId = window.setInterval(() => {\n            console.log('Tick');\n        }, 1000);\n    }\n\n    // Forgot to call stop() — the timer will live forever!\n}
\n\n

Solution: always clear timers and unsubscribe from events in the dispose or ngOnDestroy method (for Angular).

\n\n

2. Closures That Hold References

\n\n

Closures are a powerful tool, but they can accidentally hold onto huge objects:

\n\n
function createHeavyClosure() {\n    const hugeData = new Array(1000                

Blogs

Book Recommendations