-
-
Notifications
You must be signed in to change notification settings - Fork 35.2k
v8: add heap profile API #62273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
v8: add heap profile API #62273
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1617,6 +1617,30 @@ added: | |
|
|
||
| Stopping collecting the profile and the profile will be discarded. | ||
|
|
||
| ## Class: `SyncHeapProfileHandle` | ||
|
|
||
| <!-- YAML | ||
| added: REPLACEME | ||
| --> | ||
|
|
||
| ### `syncHeapProfileHandle.stop()` | ||
|
|
||
| <!-- YAML | ||
| added: REPLACEME | ||
| --> | ||
|
|
||
| * Returns: {string} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be better to return a Buffer instead. It'd give us more flexibility to add binary formats in the future. I'd like to add support at some point in the future for the pprof-derived format being defined in OpenTelemetry at the moment, which is a binary format.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, right, going for parity with the worker API. We could probably do something similar to |
||
|
|
||
| Stopping collecting the profile and return the profile data. | ||
|
|
||
| ### `syncHeapProfileHandle[Symbol.dispose]()` | ||
|
|
||
| <!-- YAML | ||
| added: REPLACEME | ||
| --> | ||
|
|
||
| Stopping collecting the profile and the profile will be discarded. | ||
|
|
||
| ## Class: `CPUProfileHandle` | ||
|
|
||
| <!-- YAML | ||
|
|
@@ -1764,6 +1788,72 @@ const profile = handle.stop(); | |
| console.log(profile); | ||
| ``` | ||
|
|
||
| ## `v8.startHeapProfile([options])` | ||
|
|
||
| <!-- YAML | ||
| added: REPLACEME | ||
| --> | ||
|
|
||
| * `options` {Object} | ||
| * `sampleInterval` {number} The average sampling interval in bytes. | ||
| **Default:** `524288` (512 KiB). | ||
| * `stackDepth` {integer} The maximum stack depth for samples. | ||
| **Default:** `16`. | ||
| * `forceGC` {boolean} Force garbage collection before taking the profile. | ||
| **Default:** `false`. | ||
| * `includeObjectsCollectedByMajorGC` {boolean} Include objects collected | ||
| by major GC. **Default:** `false`. | ||
| * `includeObjectsCollectedByMinorGC` {boolean} Include objects collected | ||
| by minor GC. **Default:** `false`. | ||
| * Returns: {SyncHeapProfileHandle} | ||
|
|
||
| Starting a heap profile then return a `SyncHeapProfileHandle` object. | ||
| This API supports `using` syntax. | ||
|
|
||
| ```cjs | ||
| const v8 = require('node:v8'); | ||
|
|
||
| const handle = v8.startHeapProfile(); | ||
| const profile = handle.stop(); | ||
| console.log(profile); | ||
| ``` | ||
|
|
||
| ```mjs | ||
| import v8 from 'node:v8'; | ||
|
|
||
| const handle = v8.startHeapProfile(); | ||
| const profile = handle.stop(); | ||
| console.log(profile); | ||
| ``` | ||
|
|
||
| With custom parameters: | ||
|
|
||
| ```cjs | ||
| const v8 = require('node:v8'); | ||
|
|
||
| const handle = v8.startHeapProfile({ | ||
| sampleInterval: 1024, | ||
| stackDepth: 8, | ||
| forceGC: true, | ||
| includeObjectsCollectedByMajorGC: true, | ||
| }); | ||
| const profile = handle.stop(); | ||
| console.log(profile); | ||
| ``` | ||
|
|
||
| ```mjs | ||
| import v8 from 'node:v8'; | ||
|
|
||
| const handle = v8.startHeapProfile({ | ||
| sampleInterval: 1024, | ||
| stackDepth: 8, | ||
| forceGC: true, | ||
| includeObjectsCollectedByMajorGC: true, | ||
| }); | ||
| const profile = handle.stop(); | ||
| console.log(profile); | ||
| ``` | ||
|
|
||
| [CppHeap]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html | ||
| [HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm | ||
| [Hook Callbacks]: #hook-callbacks | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 'use strict'; | ||
|
|
||
| const { | ||
| validateBoolean, | ||
| validateInteger, | ||
| validateInt32, | ||
| validateObject, | ||
| } = require('internal/validators'); | ||
|
|
||
| const { | ||
| kSamplingNoFlags, | ||
| kSamplingForceGC, | ||
| kSamplingIncludeObjectsCollectedByMajorGC, | ||
| kSamplingIncludeObjectsCollectedByMinorGC, | ||
| } = internalBinding('v8'); | ||
|
|
||
| function normalizeHeapProfileOptions(options = {}) { | ||
| validateObject(options, 'options'); | ||
| const { | ||
| sampleInterval = 512 * 1024, | ||
| stackDepth = 16, | ||
| forceGC = false, | ||
| includeObjectsCollectedByMajorGC = false, | ||
| includeObjectsCollectedByMinorGC = false, | ||
| } = options; | ||
|
|
||
| validateInteger(sampleInterval, 'options.sampleInterval', 1); | ||
| validateInt32(stackDepth, 'options.stackDepth', 0); | ||
| validateBoolean(forceGC, 'options.forceGC'); | ||
| validateBoolean(includeObjectsCollectedByMajorGC, | ||
| 'options.includeObjectsCollectedByMajorGC'); | ||
| validateBoolean(includeObjectsCollectedByMinorGC, | ||
| 'options.includeObjectsCollectedByMinorGC'); | ||
|
|
||
| let flags = kSamplingNoFlags; | ||
| if (forceGC) flags |= kSamplingForceGC; | ||
| if (includeObjectsCollectedByMajorGC) { | ||
| flags |= kSamplingIncludeObjectsCollectedByMajorGC; | ||
| } | ||
| if (includeObjectsCollectedByMinorGC) { | ||
| flags |= kSamplingIncludeObjectsCollectedByMinorGC; | ||
| } | ||
|
|
||
| return { sampleInterval, stackDepth, flags }; | ||
| } | ||
|
|
||
| module.exports = { | ||
| normalizeHeapProfileOptions, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be initially marked Experimental