Memory control of Node

Posted by kkessler on Mon, 28 Feb 2022 10:07:17 +0100

Memory control of Node

Allocation failed — process out of memory

If you see the above error, it means that your NodeJS application is out of memory. It consumes more memory than the allocated memory, resulting in its self termination.

When an application batch processes a large amount of data, the data processing algorithm is written in such a way that it needs to retain the objects in the heap space until the processing is completed. As processing progresses, the application gradually uses more memory, and V8 will spend more time garbage collecting to free up unused memory until it finally reaches the limit allocated to the process and leads to OOM.

Node.js runtime is very efficient in memory usage, so programs usually run well with default limits. Moreover, if the maximum heap size is not actively set, the program will use the default memory limit, and this default value will also be determined according to the node The JS version is different from the system architecture of the program.

Let's take a closer look:

1.1 garbage collection mechanism and memory limitation of V8

JavaScript, like Java, uses garbage collection mechanism for automatic memory management. For performance sensitive server-side programs, the quality of memory management and garbage collection will affect the service. In Node, all this is closely related to V8 engine.

1.2 memory limitation of V8

On the Internet, most people say that only part of the memory can be used in the Node through JavaScript (about 1.4G for 64 bits and about 0.7G for 32 bits). V8 limits memory. Therefore, under this restriction, the Node will not be able to directly operate large memory objects. However, with the version upgrade, this data seems not so absolute.

The official did not directly explain the restrictions (mainly not sure whether it can be directly analogized through buffer.constants.MAX_LENGTH), so write a small program and run it on a 64 bit system.

Node.js (64 bit measured) version limit

HeaderHeader
16.x4.0 GB
15.x4.0 GB
14.x4.0 GB
13 .x2.0 GB
12.x2.0 GB
11.x1.4 GB
10.x1.4 GB
9.x1.4 GB

Official document buffer constants. MAX_ LENGTH

  • 16.x
  • 12.x
  • 11.x

1.3 solve the problem of insufficient memory

In order to solve the OOM error, all you need to do is explicitly configure the memory limit to use node JS command line options

-max-old-space-size=<size_megabytes>

Javascript:

node --max-old-space-size=2048 index.js #increase to 2GB
node --max-old-space-size=3072 index.js #increase to 3GB
node --max-old-space-size=4096 index.js #increase to 4GB
node --max-old-space-size=5120 index.js #increase to 5GB
node --max-old-space-size=6144 index.js #increase to 6GB
node --max-old-space-size=7168 index.js #increase to 7GB
node --max-old-space-size=8192 index.js #increase to 8GB

TS node of Typescript:

node -r ts-node/register --max-old-space-size=2048 index.ts
node -r ts-node/register --max-old-space-size=3072 index.ts
node -r ts-node/register --max-old-space-size=4096 index.ts 
node -r ts-node/register --max-old-space-size=5120 index.ts 
node -r ts-node/register --max-old-space-size=6144 index.ts 
node -r ts-node/register --max-old-space-size=7168 index.ts 
node -r ts-node/register --max-old-space-size=8192 index.ts 

This can quickly solve the node JS insufficient memory!

1.4 best practices

It is recommended to always explicitly set, - Max old space size instead of relying on node JS, because in the newer node The default value in the JS version may change.

On machines with 2 GB of memory, consider setting it to 1536 (1.5 GB) to set aside some memory for other purposes and avoid memory swapping.
If you use node on a small machine, such as a Raspberry Pi board JS runs a simple Web server. You can set -- Max old space size to an appropriate small value, such as 128 MB, to avoid node Too much precious memory JS.

1.5 pm2 extension

For the specific use of pm2, please check my article Node service and pm2 actual combat

Through us, in addition to front-end project compilation (various cli, etc.), there may be insufficient memory, and the node server may also cause this problem. We can solve the front-end compilation simply by increasing the default memory, but the server-side deployment is a continuous process. We rarely start the service by directly starting the node. We usually use pm2 tool to restart the service automatically after the service is killed due to exceptions or other reasons. Due to the single thread feature of node, automatic restart can greatly improve its robustness.

Increase memory

pm2 start app.js --node-args="--max-old-space-size=1024"

Memory overflow restart

Because one of the purposes of using pm2 on our server is to automatically restart the service when there is a problem. In case of insufficient memory or insufficient consideration of the service, the service memory will crash, which is very unfriendly to the production environment. pm2 also has a restart command for insufficient memory. Once the memory is insufficient, it will automatically restart the service to prevent the whole service from getting stuck.

Basic Usage

pm2 start app.js --max_memory_restart 1024M : 

Automatically restart when the memory exceeds 1024M. If there is a thorny memory leakage problem in the project, this is a compromise.

Configuration usage

pm2 actually supports configuration files to start. We can also use the configuration files to configure commands and parameters:

pm2 startOrRestart ecosystem.json
Here is ecosystem.json Sample content:
  {
    apps : [
        {
            name: "nova",
            max_memory_restart: "1024M",
            script: "app.js"
        }
    ]
 }

Topics: node.js