From c29e40f4af9fe5c6fd52ee6f1ce7a5bdfaafc775 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 9 Oct 2020 01:07:29 +0800 Subject: [PATCH 1/3] src: add --heapsnapshot-near-heap-limit option This patch adds a --heapsnapshot-near-heap-limit CLI option that takes heap snapshots when the V8 heap is approaching the heap size limit. It will try to write the snapshots to disk before the program crashes due to OOM. --- doc/api/cli.md | 48 ++++++ doc/node.1 | 4 + src/debug_utils.h | 1 + src/env-inl.h | 16 ++ src/env.cc | 146 ++++++++++++++++++ src/env.h | 10 ++ src/heap_utils.cc | 6 +- src/inspector_profiler.cc | 20 +-- src/node.cc | 4 + src/node_internals.h | 4 + src/node_main_instance.cc | 2 + src/node_options.cc | 12 ++ src/node_options.h | 1 + src/node_worker.cc | 5 + test/fixtures/workload/bounded.js | 22 +++ test/fixtures/workload/grow-worker.js | 14 ++ test/fixtures/workload/grow.js | 12 ++ ...st-heapsnapshot-near-heap-limit-bounded.js | 36 +++++ .../test-heapsnapshot-near-heap-limit.js | 106 +++++++++++++ .../test-heapsnapshot-near-heap-limit-big.js | 43 ++++++ 20 files changed, 491 insertions(+), 21 deletions(-) create mode 100644 test/fixtures/workload/bounded.js create mode 100644 test/fixtures/workload/grow-worker.js create mode 100644 test/fixtures/workload/grow.js create mode 100644 test/parallel/test-heapsnapshot-near-heap-limit-bounded.js create mode 100644 test/parallel/test-heapsnapshot-near-heap-limit.js create mode 100644 test/pummel/test-heapsnapshot-near-heap-limit-big.js diff --git a/doc/api/cli.md b/doc/api/cli.md index cb1d1ff2f43f34..27977f20ed0246 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -333,6 +333,53 @@ reference. Code may break under this flag. `--require` runs prior to freezing intrinsics in order to allow polyfills to be added. +### `--heapsnapshot-near-heap-limit=max_count` + + +> Stability: 1 - Experimental + +Writes a V8 heap snapshot to disk when the V8 heap usage is approaching the +heap limit. `count` should be either -1 (in which case no snapshots would be +written), or a positive integer (in which case Node.js will write no more than +`max_count` snapshots to disk). + +When generating snapshots, garbage collection may be triggered and bring +the heap usage down, therefore multiple snapshots may be written to disk +before the Node.js instance finally runs out of memory. These heap snapshots +can be compared to determine what objects are being allocated during the +time consecutive snapshots are taken. It's not guaranteed that Node.js will +write exactly `max_count` snapshots to disk, but it will try +its best to generate at least one and up to `max_count` snapshots before the +Node.js instance runs out of memory. + +Generating V8 snapshots takes time and memory (both memory managed by the +V8 heap and native memory outside the V8 heap). The bigger the heap is, +the more resources it needs. Node.js will adjust the V8 heap to accommondate +the additional V8 heap memory overhead, and try its best to avoid using up +all the memory avialable to the process. When the process uses +more memory than the system deems appropriate, the process may be terminated +abruptly by the system, depending on the system configuration. + +```console +$ node --max-old-space-size=100 --heapsnapshot-near-heap-limit=3 index.js +Wrote snapshot to Heap.20200430.100036.49580.0.001.heapsnapshot +Wrote snapshot to Heap.20200430.100037.49580.0.002.heapsnapshot +Wrote snapshot to Heap.20200430.100038.49580.0.003.heapsnapshot + +<--- Last few GCs ---> + +[49580:0x110000000] 4826 ms: Mark-sweep 130.6 (147.8) -> 130.5 (147.8) MB, 27.4 / 0.0 ms (average mu = 0.126, current mu = 0.034) allocation failure scavenge might not succeed +[49580:0x110000000] 4845 ms: Mark-sweep 130.6 (147.8) -> 130.6 (147.8) MB, 18.8 / 0.0 ms (average mu = 0.088, current mu = 0.031) allocation failure scavenge might not succeed + + +<--- JS stacktrace ---> + +FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory +.... +``` + ### `--heapsnapshot-signal=signal`