From ae3929e958dfa72bcf9f9efeb53c89f825c228ce Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sat, 8 Feb 2020 01:49:43 +0800 Subject: [PATCH] vm: implement vm.measureMemory() for per-context memory measurement This patch implements `vm.measureMemory()` with the new `v8::Isolate::MeasureMemory()` API to measure per-context memory usage. This should be experimental, since detailed memory measurement requires further integration with the V8 API that should be available in a future V8 update. PR-URL: https://github.com/nodejs/node/pull/31824 Refs: https://github.com/ulan/performance-measure-memory Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Denys Otrishko Reviewed-By: Colin Ihrig --- doc/api/errors.md | 8 +++ doc/api/vm.md | 50 ++++++++++++++++++ lib/internal/errors.js | 1 + lib/vm.js | 37 ++++++++++++- src/node_contextify.cc | 44 ++++++++++++++++ test/parallel/test-vm-measure-memory.js | 70 +++++++++++++++++++++++++ 6 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-vm-measure-memory.js diff --git a/doc/api/errors.md b/doc/api/errors.md index a7726cd03019cd..15be1fd2061618 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -710,6 +710,14 @@ STDERR/STDOUT, and the data's length is longer than the `maxBuffer` option. `Console` was instantiated without `stdout` stream, or `Console` has a non-writable `stdout` or `stderr` stream. + +### `ERR_CONTEXT_NOT_INITIALIZED` + +The vm context passed into the API is not yet initialized. This could happen +when an error occurs (and is caught) during the creation of the +context, for example, when the allocation fails or the maximum call stack +size is reached when the context is created. + ### `ERR_CONSTRUCT_CALL_REQUIRED` diff --git a/doc/api/vm.md b/doc/api/vm.md index bd64b23484eb24..ed676414471b8e 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -295,6 +295,56 @@ console.log(globalVar); // 1000 ``` +## `vm.measureMemory([options])` + + + +> Stability: 1 - Experimental + +Measure the memory known to V8 and used by the current execution context +or a specified context. + +* `options` {Object} Optional. + * `mode` {string} Either `'summary'` or `'detailed'`. + **Default:** `'summary'` + * `context` {Object} Optional. A [contextified][] object returned + by `vm.createContext()`. If not specified, measure the memory + usage of the current context where `vm.measureMemory()` is invoked. +* Returns: {Promise} If the memory is successfully measured the promise will + resolve with an object containing information about the memory usage. + +The format of the object that the returned Promise may resolve with is +specific to the V8 engine and may change from one version of V8 to the next. + +The returned result is different from the statistics returned by +`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measures +the memory reachable by V8 from a specific context, while +`v8.getHeapSpaceStatistics()` measures the memory used by an instance +of V8 engine, which can switch among multiple contexts that reference +objects in the heap of one engine. + +```js +const vm = require('vm'); +// Measure the memory used by the current context and return the result +// in summary. +vm.measureMemory({ mode: 'summary' }) + // Is the same as vm.measureMemory() + .then((result) => { + // The current format is: + // { total: { jsMemoryEstimate: 2211728, jsMemoryRange: [ 0, 2211728 ] } } + console.log(result); + }); + +const context = vm.createContext({}); +vm.measureMemory({ mode: 'detailed' }, context) + .then((result) => { + // At the moment the detailed format is the same as the summary one. + console.log(result); + }); +``` + ## Class: `vm.Module`