| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1617,6 +1617,32 @@ added: | |||
| 1617 | 1617 | ||
| 1618 | 1618 | Stopping collecting the profile and the profile will be discarded. | |
| 1619 | 1619 | ||
| 1620 | + ## Class: `SyncHeapProfileHandle` | ||
| 1621 | + | ||
| 1622 | + <!-- YAML | ||
| 1623 | + added: REPLACEME | ||
| 1624 | + --> | ||
| 1625 | + | ||
| 1626 | + > Stability: 1 - Experimental | ||
| 1627 | + | ||
| 1628 | + ### `syncHeapProfileHandle.stop()` | ||
| 1629 | + | ||
| 1630 | + <!-- YAML | ||
| 1631 | + added: REPLACEME | ||
| 1632 | + --> | ||
| 1633 | + | ||
| 1634 | + * Returns: {string} | ||
| 1635 | + | ||
| 1636 | + Stopping collecting the profile and return the profile data. | ||
| 1637 | + | ||
| 1638 | + ### `syncHeapProfileHandle[Symbol.dispose]()` | ||
| 1639 | + | ||
| 1640 | + <!-- YAML | ||
| 1641 | + added: REPLACEME | ||
| 1642 | + --> | ||
| 1643 | + | ||
| 1644 | + Stopping collecting the profile and the profile will be discarded. | ||
| 1645 | + | ||
| 1620 | 1646 | ## Class: `CPUProfileHandle` | |
| 1621 | 1647 | ||
| 1622 | 1648 | <!-- YAML | |
@@ -1764,6 +1790,72 @@ const profile = handle.stop(); | |||
| 1764 | 1790 | console.log(profile); | |
| 1765 | 1791 | ``` | |
| 1766 | 1792 | ||
| 1793 | + ## `v8.startHeapProfile([options])` | ||
| 1794 | + | ||
| 1795 | + <!-- YAML | ||
| 1796 | + added: REPLACEME | ||
| 1797 | + --> | ||
| 1798 | + | ||
| 1799 | + * `options` {Object} | ||
| 1800 | + * `sampleInterval` {number} The average sampling interval in bytes. | ||
| 1801 | + **Default:** `524288` (512 KiB). | ||
| 1802 | + * `stackDepth` {integer} The maximum stack depth for samples. | ||
| 1803 | + **Default:** `16`. | ||
| 1804 | + * `forceGC` {boolean} Force garbage collection before taking the profile. | ||
| 1805 | + **Default:** `false`. | ||
| 1806 | + * `includeObjectsCollectedByMajorGC` {boolean} Include objects collected | ||
| 1807 | + by major GC. **Default:** `false`. | ||
| 1808 | + * `includeObjectsCollectedByMinorGC` {boolean} Include objects collected | ||
| 1809 | + by minor GC. **Default:** `false`. | ||
| 1810 | + * Returns: {SyncHeapProfileHandle} | ||
| 1811 | + | ||
| 1812 | + Starting a heap profile then return a `SyncHeapProfileHandle` object. | ||
| 1813 | + This API supports `using` syntax. | ||
| 1814 | + | ||
| 1815 | + ```cjs | ||
| 1816 | + const v8 = require('node:v8'); | ||
| 1817 | + | ||
| 1818 | + const handle = v8.startHeapProfile(); | ||
| 1819 | + const profile = handle.stop(); | ||
| 1820 | + console.log(profile); | ||
| 1821 | + ``` | ||
| 1822 | + | ||
| 1823 | + ```mjs | ||
| 1824 | + import v8 from 'node:v8'; | ||
| 1825 | + | ||
| 1826 | + const handle = v8.startHeapProfile(); | ||
| 1827 | + const profile = handle.stop(); | ||
| 1828 | + console.log(profile); | ||
| 1829 | + ``` | ||
| 1830 | + | ||
| 1831 | + With custom parameters: | ||
| 1832 | + | ||
| 1833 | + ```cjs | ||
| 1834 | + const v8 = require('node:v8'); | ||
| 1835 | + | ||
| 1836 | + const handle = v8.startHeapProfile({ | ||
| 1837 | + sampleInterval: 1024, | ||
| 1838 | + stackDepth: 8, | ||
| 1839 | + forceGC: true, | ||
| 1840 | + includeObjectsCollectedByMajorGC: true, | ||
| 1841 | + }); | ||
| 1842 | + const profile = handle.stop(); | ||
| 1843 | + console.log(profile); | ||
| 1844 | + ``` | ||
| 1845 | + | ||
| 1846 | + ```mjs | ||
| 1847 | + import v8 from 'node:v8'; | ||
| 1848 | + | ||
| 1849 | + const handle = v8.startHeapProfile({ | ||
| 1850 | + sampleInterval: 1024, | ||
| 1851 | + stackDepth: 8, | ||
| 1852 | + forceGC: true, | ||
| 1853 | + includeObjectsCollectedByMajorGC: true, | ||
| 1854 | + }); | ||
| 1855 | + const profile = handle.stop(); | ||
| 1856 | + console.log(profile); | ||
| 1857 | + ``` | ||
| 1858 | + | ||
| 1767 | 1859 | [CppHeap]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html | |
| 1768 | 1860 | [HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm | |
| 1769 | 1861 | [Hook Callbacks]: #hook-callbacks | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2005,14 +2005,25 @@ w.on('online', async () => { | |||
| 2005 | 2005 | }); | |
| 2006 | 2006 | ``` | |
| 2007 | 2007 | ||
| 2008 | - ### `worker.startHeapProfile()` | ||
| 2008 | + ### `worker.startHeapProfile([options])` | ||
| 2009 | 2009 | ||
| 2010 | 2010 | <!-- YAML | |
| 2011 | 2011 | added: | |
| 2012 | 2012 | - v24.9.0 | |
| 2013 | 2013 | - v22.20.0 | |
| 2014 | 2014 | --> | |
| 2015 | 2015 | ||
| 2016 | + * `options` {Object} | ||
| 2017 | + * `sampleInterval` {number} The average sampling interval in bytes. | ||
| 2018 | + **Default:** `524288` (512 KiB). | ||
| 2019 | + * `stackDepth` {integer} The maximum stack depth for samples. | ||
| 2020 | + **Default:** `16`. | ||
| 2021 | + * `forceGC` {boolean} Force garbage collection before taking the profile. | ||
| 2022 | + **Default:** `false`. | ||
| 2023 | + * `includeObjectsCollectedByMajorGC` {boolean} Include objects collected | ||
| 2024 | + by major GC. **Default:** `false`. | ||
| 2025 | + * `includeObjectsCollectedByMinorGC` {boolean} Include objects collected | ||
| 2026 | + by minor GC. **Default:** `false`. | ||
| 2016 | 2027 | * Returns: {Promise} | |
| 2017 | 2028 | ||
| 2018 | 2029 | Starting a Heap profile then return a Promise that fulfills with an error | |
@@ -2034,6 +2045,22 @@ worker.on('online', async () => { | |||
| 2034 | 2045 | }); | |
| 2035 | 2046 | ``` | |
| 2036 | 2047 | ||
| 2048 | + ```mjs | ||
| 2049 | + import { Worker } from 'node:worker_threads'; | ||
| 2050 | + | ||
| 2051 | + const worker = new Worker(` | ||
| 2052 | + const { parentPort } = require('node:worker_threads'); | ||
| 2053 | + parentPort.on('message', () => {}); | ||
| 2054 | + `, { eval: true }); | ||
| 2055 | + | ||
| 2056 | + worker.on('online', async () => { | ||
| 2057 | + const handle = await worker.startHeapProfile(); | ||
| 2058 | + const profile = await handle.stop(); | ||
| 2059 | + console.log(profile); | ||
| 2060 | + worker.terminate(); | ||
| 2061 | + }); | ||
| 2062 | + ``` | ||
| 2063 | + | ||
| 2037 | 2064 | `await using` example. | |
| 2038 | 2065 | ||
| 2039 | 2066 | ```cjs | |
@@ -2050,6 +2077,20 @@ w.on('online', async () => { | |||
| 2050 | 2077 | }); | |
| 2051 | 2078 | ``` | |
| 2052 | 2079 | ||
| 2080 | + ```mjs | ||
| 2081 | + import { Worker } from 'node:worker_threads'; | ||
| 2082 | + | ||
| 2083 | + const w = new Worker(` | ||
| 2084 | + const { parentPort } = require('node:worker_threads'); | ||
| 2085 | + parentPort.on('message', () => {}); | ||
| 2086 | + `, { eval: true }); | ||
| 2087 | + | ||
| 2088 | + w.on('online', async () => { | ||
| 2089 | + // Stop profile automatically when return and profile will be discarded | ||
| 2090 | + await using handle = await w.startHeapProfile(); | ||
| 2091 | + }); | ||
| 2092 | + ``` | ||
| 2093 | + | ||
| 2053 | 2094 | ### `worker.stderr` | |
| 2054 | 2095 | ||
| 2055 | 2096 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,49 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const { | ||
| 4 | + validateBoolean, | ||
| 5 | + validateInteger, | ||
| 6 | + validateInt32, | ||
| 7 | + validateObject, | ||
| 8 | + } = require('internal/validators'); | ||
| 9 | + | ||
| 10 | + const { | ||
| 11 | + kSamplingNoFlags, | ||
| 12 | + kSamplingForceGC, | ||
| 13 | + kSamplingIncludeObjectsCollectedByMajorGC, | ||
| 14 | + kSamplingIncludeObjectsCollectedByMinorGC, | ||
| 15 | + } = internalBinding('v8'); | ||
| 16 | + | ||
| 17 | + function normalizeHeapProfileOptions(options = {}) { | ||
| 18 | + validateObject(options, 'options'); | ||
| 19 | + const { | ||
| 20 | + sampleInterval = 512 * 1024, | ||
| 21 | + stackDepth = 16, | ||
| 22 | + forceGC = false, | ||
| 23 | + includeObjectsCollectedByMajorGC = false, | ||
| 24 | + includeObjectsCollectedByMinorGC = false, | ||
| 25 | + } = options; | ||
| 26 | + | ||
| 27 | + validateInteger(sampleInterval, 'options.sampleInterval', 1); | ||
| 28 | + validateInt32(stackDepth, 'options.stackDepth', 0); | ||
| 29 | + validateBoolean(forceGC, 'options.forceGC'); | ||
| 30 | + validateBoolean(includeObjectsCollectedByMajorGC, | ||
| 31 | + 'options.includeObjectsCollectedByMajorGC'); | ||
| 32 | + validateBoolean(includeObjectsCollectedByMinorGC, | ||
| 33 | + 'options.includeObjectsCollectedByMinorGC'); | ||
| 34 | + | ||
| 35 | + let flags = kSamplingNoFlags; | ||
| 36 | + if (forceGC) flags |= kSamplingForceGC; | ||
| 37 | + if (includeObjectsCollectedByMajorGC) { | ||
| 38 | + flags |= kSamplingIncludeObjectsCollectedByMajorGC; | ||
| 39 | + } | ||
| 40 | + if (includeObjectsCollectedByMinorGC) { | ||
| 41 | + flags |= kSamplingIncludeObjectsCollectedByMinorGC; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + return { sampleInterval, stackDepth, flags }; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + module.exports = { | ||
| 48 | + normalizeHeapProfileOptions, | ||
| 49 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -65,7 +65,13 @@ const { | |||
| 65 | 65 | constructSharedArrayBuffer, | |
| 66 | 66 | kEmptyObject, | |
| 67 | 67 | } = require('internal/util'); | |
| 68 | - const { validateArray, validateString, validateObject, validateNumber } = require('internal/validators'); | ||
| 68 | + const { | ||
| 69 | + validateArray, | ||
| 70 | + validateString, | ||
| 71 | + validateObject, | ||
| 72 | + validateNumber, | ||
| 73 | + } = require('internal/validators'); | ||
| 74 | + let normalizeHeapProfileOptions; | ||
| 69 | 75 | const { | |
| 70 | 76 | throwIfBuildingSnapshot, | |
| 71 | 77 | } = require('internal/v8/startup_snapshot'); | |
@@ -582,8 +588,22 @@ class Worker extends EventEmitter { | |||
| 582 | 588 | }); | |
| 583 | 589 | } | |
| 584 | 590 | ||
| 585 | - startHeapProfile() { | ||
| 586 | - const startTaker = this[kHandle]?.startHeapProfile(); | ||
| 591 | + /** | ||
| 592 | + * @param {object} [options] | ||
| 593 | + * @param {number} [options.sampleInterval] | ||
| 594 | + * @param {number} [options.stackDepth] | ||
| 595 | + * @param {boolean} [options.forceGC] | ||
| 596 | + * @param {boolean} [options.includeObjectsCollectedByMajorGC] | ||
| 597 | + * @param {boolean} [options.includeObjectsCollectedByMinorGC] | ||
| 598 | + * @returns {Promise} | ||
| 599 | + */ | ||
| 600 | + startHeapProfile(options) { | ||
| 601 | + normalizeHeapProfileOptions ??= | ||
| 602 | + require('internal/v8/heap_profile').normalizeHeapProfileOptions; | ||
| 603 | + const { sampleInterval, stackDepth, flags } = | ||
| 604 | + normalizeHeapProfileOptions(options); | ||
| 605 | + const startTaker = this[kHandle]?.startHeapProfile( | ||
| 606 | + sampleInterval, stackDepth, flags); | ||
| 587 | 607 | return new Promise((resolve, reject) => { | |
| 588 | 608 | if (!startTaker) return reject(new ERR_WORKER_NOT_RUNNING()); | |
| 589 | 609 | startTaker.ondone = (err) => { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -40,8 +40,8 @@ const { | |||
| 40 | 40 | const { Buffer } = require('buffer'); | |
| 41 | 41 | const { | |
| 42 | 42 | validateString, | |
| 43 | - validateUint32, | ||
| 44 | 43 | validateOneOf, | |
| 44 | + validateUint32, | ||
| 45 | 45 | } = require('internal/validators'); | |
| 46 | 46 | const { | |
| 47 | 47 | Serializer, | |
@@ -50,6 +50,9 @@ const { | |||
| 50 | 50 | const { | |
| 51 | 51 | namespace: startupSnapshot, | |
| 52 | 52 | } = require('internal/v8/startup_snapshot'); | |
| 53 | + const { | ||
| 54 | + normalizeHeapProfileOptions, | ||
| 55 | + } = require('internal/v8/heap_profile'); | ||
| 53 | 56 | ||
| 54 | 57 | let profiler = {}; | |
| 55 | 58 | if (internalBinding('config').hasInspector) { | |
@@ -115,6 +118,8 @@ const { | |||
| 115 | 118 | setFlagsFromString: _setFlagsFromString, | |
| 116 | 119 | startCpuProfile: _startCpuProfile, | |
| 117 | 120 | stopCpuProfile: _stopCpuProfile, | |
| 121 | + startHeapProfile: _startHeapProfile, | ||
| 122 | + stopHeapProfile: _stopHeapProfile, | ||
| 118 | 123 | isStringOneByteRepresentation: _isStringOneByteRepresentation, | |
| 119 | 124 | updateHeapStatisticsBuffer, | |
| 120 | 125 | updateHeapSpaceStatisticsBuffer, | |
@@ -191,6 +196,22 @@ class SyncCPUProfileHandle { | |||
| 191 | 196 | } | |
| 192 | 197 | } | |
| 193 | 198 | ||
| 199 | + class SyncHeapProfileHandle { | ||
| 200 | + #stopped = false; | ||
| 201 | + | ||
| 202 | + stop() { | ||
| 203 | + if (this.#stopped) { | ||
| 204 | + return; | ||
| 205 | + } | ||
| 206 | + this.#stopped = true; | ||
| 207 | + return _stopHeapProfile(); | ||
| 208 | + }; | ||
| 209 | + | ||
| 210 | + [SymbolDispose]() { | ||
| 211 | + this.stop(); | ||
| 212 | + } | ||
| 213 | + } | ||
| 214 | + | ||
| 194 | 215 | /** | |
| 195 | 216 | * Starting CPU Profile. | |
| 196 | 217 | * @returns {SyncCPUProfileHandle} | |
@@ -200,6 +221,23 @@ function startCpuProfile() { | |||
| 200 | 221 | return new SyncCPUProfileHandle(id); | |
| 201 | 222 | } | |
| 202 | 223 | ||
| 224 | + /** | ||
| 225 | + * Starting Heap Profile. | ||
| 226 | + * @param {object} [options] | ||
| 227 | + * @param {number} [options.sampleInterval] | ||
| 228 | + * @param {number} [options.stackDepth] | ||
| 229 | + * @param {boolean} [options.forceGC] | ||
| 230 | + * @param {boolean} [options.includeObjectsCollectedByMajorGC] | ||
| 231 | + * @param {boolean} [options.includeObjectsCollectedByMinorGC] | ||
| 232 | + * @returns {SyncHeapProfileHandle} | ||
| 233 | + */ | ||
| 234 | + function startHeapProfile(options) { | ||
| 235 | + const { sampleInterval, stackDepth, flags } = | ||
| 236 | + normalizeHeapProfileOptions(options); | ||
| 237 | + _startHeapProfile(sampleInterval, stackDepth, flags); | ||
| 238 | + return new SyncHeapProfileHandle(); | ||
| 239 | + } | ||
| 240 | + | ||
| 203 | 241 | /** | |
| 204 | 242 | * Return whether this string uses one byte as underlying representation or not. | |
| 205 | 243 | * @param {string} content | |
@@ -518,4 +556,5 @@ module.exports = { | |||
| 518 | 556 | GCProfiler, | |
| 519 | 557 | isStringOneByteRepresentation, | |
| 520 | 558 | startCpuProfile, | |
| 559 | + startHeapProfile, | ||
| 521 | 560 | }; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments