Skip to content

Commit 98dd619

Browse files
committed
feat(learn): add article on tuning memory
1 parent 52f32bb commit 98dd619

File tree

4 files changed

+143
-3
lines changed

4 files changed

+143
-3
lines changed

apps/site/pages/en/learn/diagnostics/memory/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ leaks is possible through retainers. As Node.js applications are usually
1414
multi-tenant, business critical, and long-running, providing an accessible and
1515
efficient way of finding a memory leak is essential.
1616

17+
You can also fine-tune memory to get specific results. Check out
18+
[Understanding and Tuning Memory](/learn/diagnostics/memory/understanding-and-tuning-memory) for more details.
19+
1720
### Symptoms
1821

1922
The user observes continuously increasing memory usage _(can be fast or slow,
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
title: Understanding and Tuning Memory
3+
layout: learn
4+
authors: avivkeller
5+
---
6+
7+
# Understanding and Tuning Memory
8+
9+
Node.js, built on Google’s V8 JavaScript engine, offers a powerful runtime for running JavaScript on the server side. However, as your applications grow, managing memory becomes a critical task for maintaining optimal performance and avoiding problems like memory leaks or crashes. In this article, we’ll explore how to monitor, manage, and optimize memory usage within Node.js. We’ll also cover important V8 concepts like the heap and garbage collection and discuss how to use command-line flags to fine-tune memory behavior.
10+
11+
## How V8 Manages Memory
12+
13+
At its core, V8 divides memory into several parts, with two primary areas being the **heap** and the **stack**. Understanding these spaces, especially how the heap is managed, is key to improving memory usage in your app.
14+
15+
### The Heap
16+
17+
V8 manages memory using two main areas in the heap:
18+
19+
1. **New Space**: This is where new, short-lived objects are allocated. Because objects here are expected to be temporary, garbage collection occurs frequently, allowing memory to be reclaimed quickly.
20+
21+
2. **Old Space**: Objects that survive several garbage collection cycles in the New Space are moved to the Old Space. Since these objects are more persistent, garbage collection in this space occurs less often but is more resource-intensive when it happens.
22+
23+
In V8, memory for JavaScript objects, arrays, and functions is allocated in the **heap**. The size of the heap is not fixed, and exceeding the available memory can result in an "out-of-memory" error, causing your application to crash.
24+
25+
To check the current heap size limit, you can use the `v8` module.
26+
27+
```cjs
28+
const v8 = require('node:v8');
29+
const heapSizeLimit = v8.getHeapStatistics().heap_size_limit;
30+
const heapSizeInGB = heapSizeLimit / (1024 * 1024 * 1024);
31+
32+
console.log(`${heapSizeInGB} GB`);
33+
```
34+
35+
This will output the maximum heap size in gigabytes, which is based on your system's available memory.
36+
37+
### The Stack
38+
39+
In addition to the heap, V8 also uses the **stack** for memory management. The stack is a region of memory used to store local variables and function call information. Unlike the heap, which is managed by V8's garbage collector, the stack operates on a Last In, First Out (LIFO) principle.
40+
41+
Whenever a function is called, a new frame is pushed onto the stack. When the function returns, its frame is popped off. The stack is much smaller in size compared to the heap, but it is faster for memory allocation and deallocation. However, the stack has a limited size, and excessive use of memory (such as with deep recursion) can result in a **stack overflow**.
42+
43+
## Monitoring Memory Usage
44+
45+
Before tuning memory usage, it’s important to understand how much memory your application is consuming. Node.js and V8 provide several tools for monitoring memory usage.
46+
47+
### Using `process.memoryUsage()`
48+
49+
The `process.memoryUsage()` method provides insights into how much memory your Node.js process is using. It returns an object with details like:
50+
51+
- **`rss`** (Resident Set Size): The total memory allocated to your process, including heap and other areas.
52+
- **`heapTotal`**: The total memory allocated for the heap.
53+
- **`heapUsed`**: The memory currently in use within the heap.
54+
- **`external`**: Memory used by external resources like bindings to C++ libraries.
55+
- **`arrayBuffers`**: Memory allocated to various Buffer-like objects.
56+
57+
Here’s an example:
58+
59+
```javascript
60+
console.log(process.memoryUsage());
61+
```
62+
63+
The output will look like:
64+
65+
```json
66+
{
67+
"rss": 25837568,
68+
"heapTotal": 5238784,
69+
"heapUsed": 3666120,
70+
"external": 1274076,
71+
"arrayBuffers": 10515
72+
}
73+
```
74+
75+
By monitoring these values over time, you can identify if memory usage increases unexpectedly, a common sign of memory leaks.
76+
77+
## Command-Line Flags for Memory Tuning
78+
79+
Node.js offers several command-line flags that help you fine-tune memory-related settings. Below are some key options you can use to optimize memory usage.
80+
81+
### `--max-old-space-size`
82+
83+
This flag sets a limit on the size of the **Old Space** in the V8 heap, where long-lived objects are stored. If your application uses a significant amount of memory, you might need to adjust this limit.
84+
85+
To increase the Old Space limit to 4 GB, for example, use:
86+
87+
```bash
88+
node --max-old-space-size=4096 app.js
89+
```
90+
91+
This sets the Old Space size to 4096 MB (4 GB), but you should adjust this based on your system's available memory.
92+
93+
### `--max-semi-space-size`
94+
95+
The `--max-semi-space-size` flag controls the size of the **New Space** in the V8 heap. New Space stores newly created objects, which are garbage collected frequently. You can adjust this size if you want to optimize how much memory the New Space can use before triggering garbage collection.
96+
97+
For example:
98+
99+
```bash
100+
node --max-semi-space-size=512 app.js
101+
```
102+
103+
This limits the New Space to 512 MB, which can help optimize garbage collection behavior.
104+
105+
### `--gc-interval`
106+
107+
This flag adjusts how frequently garbage collection cycles occur. V8 uses its internal heuristics by default, but you can change this to control the collection interval.
108+
109+
To set the interval to 100 ms:
110+
111+
```bash
112+
node --gc-interval=100 app.js
113+
```
114+
115+
While this setting is not commonly used, it can be helpful for fine-tuning performance in specific scenarios.
116+
117+
### `--expose-gc`
118+
119+
With the `--expose-gc` flag, you can manually trigger garbage collection from your application code. This is useful in scenarios where you want more control over when garbage collection happens.
120+
121+
To enable it, start your app with:
122+
123+
```bash
124+
node --expose-gc app.js
125+
```
126+
127+
Then, within your code, you can call:
128+
129+
```javascript
130+
global.gc();
131+
```
132+
133+
Keep in mind that forcing garbage collection too frequently can hurt performance, so use this feature sparingly.
134+
135+
By adjusting settings for the Old Space and New Space sizes, triggering garbage collection manually, and configuring heap limits, you can optimize your application’s memory usage and improve its overall performance.

apps/site/pages/en/learn/diagnostics/user-journey.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ layout: learn
55

66
# User Journey
77

8-
These diagnostics guides were created by the [Diagnostics Working Group][] with the
9-
objective of providing guidance when diagnosing an issue in a user's
10-
application.
8+
These diagnostics guides were created by the [Diagnostics Working Group][]
9+
and the [Node.js Website Team][] with the objective of providing guidance
10+
when diagnosing an issue in a user's application.
1111

1212
The documentation project is organized based on user journey. Those journeys
1313
are a coherent set of step-by-step procedures that a user can follow to
1414
root-cause their issues.
1515

1616
[Diagnostics Working Group]: https://github.com/nodejs/diagnostics
17+
[Node.js Website Team]: https://github.com/nodejs/nodejs.org

packages/i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"links": {
109109
"diagnostics": "Diagnostics",
110110
"userJourney": "User Journey",
111+
"understandingAndFineTuningMemory": "Understanding and Fine Tuning Memory",
111112
"memory": "Memory",
112113
"liveDebugging": "Live Debugging",
113114
"poorPerformance": "Poor Performance",

0 commit comments

Comments
 (0)