Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect v8 heap usage is close to limit in Node.js

Now I use:

const v8 = require('v8');

let heap = v8.getHeapStatistics();
let usage = 100 / heap.heap_size_limit * heap.used_heap_size;

if (usage > 90) {
    console.log(`V8 heap usage close to the limit (${usage.toFixed()}%)`);
} else if (usage > 95) {
    console.log(`V8 heap usage very close to the limit (${usage.toFixed()}%)`);
}

This solution not properly work.

When I try this command: node --max-old-space-size=100 index.js My process down by unable allocate memory, when my script calculate ~56%

getHeapStatistics().heap_size_limit is 178 MB
getHeapStatistics().used_heap_size is ~95 MB

How to detect situation more exactly, when we can get out of memory error?

like image 721
buinskii Avatar asked Oct 20 '16 15:10

buinskii


1 Answers

The v8 heap is actually split into regions or spaces: new_space, old_space, code_space, map_space and large_object_space. The first two roughly corresponds to nursery and tenured object heap, though in theory objects can sit in any of the five spaces.

A more accurate measure would be to use space_size and space_used_size of the old_space.

var space = v8.getHeapSpaceStatistics();
var old_space_total = space[1].space_size;
var old_space_used = space[1].space_used_size;
var usage = 100 / old_space_total * old_space_used;
if (usage > 90) {
    console.log(`V8 heap usage close to the limit (${usage.toFixed()}%)`);
} else if (usage > 95) {
    console.log(`V8 heap usage very close to the limit (${usage.toFixed()}%)`);
}

Statistics just before the memory exhaustion:

#node --max_old_space_size=200 heap.js
...
{ total_heap_size: 243306496,
  total_heap_size_executable: 5242880,
  total_physical_size: 243306496,
  total_available_size: 19149632,
  used_heap_size: 215801616,
  heap_size_limit: 243269632 }
[ { space_name: 'new_space',
    space_size: 33554432,
    space_used_size: 16464888,
    space_available_size: 41992,
    physical_space_size: 33554432 },
  { space_name: 'old_space',
    space_size: 205475840,
    space_used_size: 197215464,
    space_available_size: 18462512,
    physical_space_size: 205475840 },
  { space_name: 'code_space',
    space_size: 2097152,
    space_used_size: 680416,
    space_available_size: 617024,
    physical_space_size: 2097152 },
  { space_name: 'map_space',
    space_size: 2179072,
    space_used_size: 1452528,
    space_available_size: 18800,
    physical_space_size: 2179072 },
  { space_name: 'large_object_space',
    space_size: 0,
    space_used_size: 0,
    space_available_size: 0,
    physical_space_size: 0 } ]
V8 heap usage close to the limit (96%)
...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

As we can see, the total_heap_size: 243306496 is actually a summation of new space(33554432), old space (205475840), code (2097152), map (2179072), large object(0).

And as you can see, all other spaces are healthy, while the old space is nearing exhaustion, and the actual exhaustion came from there.

Hope this helps.

like image 93
Gireesh Punathil Avatar answered Oct 21 '22 12:10

Gireesh Punathil