| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -125,6 +125,20 @@ Creates a new `PerformanceMark` entry in the Performance Timeline. A | |||
| 125 | 125 | `performanceEntry.duration` is always `0`. Performance marks are used | |
| 126 | 126 | to mark specific significant moments in the Performance Timeline. | |
| 127 | 127 | ||
| 128 | + ### performance.maxEntries | ||
| 129 | + <!-- YAML | ||
| 130 | + added: REPLACEME | ||
| 131 | + --> | ||
| 132 | + | ||
| 133 | + Value: {number} | ||
| 134 | + | ||
| 135 | + The maximum number of Performance Entry items that should be added to the | ||
| 136 | + Performance Timeline. This limit is not strictly enforced, but a process | ||
| 137 | + warning will be emitted if the number of entries in the timeline exceeds | ||
| 138 | + this limit. | ||
| 139 | + | ||
| 140 | + Defaults to 150. | ||
| 141 | + | ||
| 128 | 142 | ### performance.measure(name, startMark, endMark) | |
| 129 | 143 | <!-- YAML | |
| 130 | 144 | added: v8.5.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,6 +53,9 @@ const kClearEntry = Symbol('clear-entry'); | |||
| 53 | 53 | const kGetEntries = Symbol('get-entries'); | |
| 54 | 54 | const kIndex = Symbol('index'); | |
| 55 | 55 | const kMarks = Symbol('marks'); | |
| 56 | + const kCount = Symbol('count'); | ||
| 57 | + const kMaxCount = Symbol('max-count'); | ||
| 58 | + const kDefaultMaxCount = 150; | ||
| 56 | 59 | ||
| 57 | 60 | observerCounts[NODE_PERFORMANCE_ENTRY_TYPE_MARK] = 1; | |
| 58 | 61 | observerCounts[NODE_PERFORMANCE_ENTRY_TYPE_MEASURE] = 1; | |
@@ -250,20 +253,32 @@ const nodeTiming = new PerformanceNodeTiming(); | |||
| 250 | 253 | // Maintains a list of entries as a linked list stored in insertion order. | |
| 251 | 254 | class PerformanceObserverEntryList { | |
| 252 | 255 | constructor() { | |
| 253 | - Object.defineProperty(this, kEntries, { | ||
| 254 | - writable: true, | ||
| 255 | - enumerable: false, | ||
| 256 | - value: {} | ||
| 256 | + Object.defineProperties(this, { | ||
| 257 | + [kEntries]: { | ||
| 258 | + writable: true, | ||
| 259 | + enumerable: false, | ||
| 260 | + value: {} | ||
| 261 | + }, | ||
| 262 | + [kCount]: { | ||
| 263 | + writable: true, | ||
| 264 | + enumerable: false, | ||
| 265 | + value: 0 | ||
| 266 | + } | ||
| 257 | 267 | }); | |
| 258 | 268 | L.init(this[kEntries]); | |
| 259 | 269 | } | |
| 260 | 270 | ||
| 261 | 271 | [kInsertEntry](entry) { | |
| 262 | 272 | const item = { entry }; | |
| 263 | 273 | L.append(this[kEntries], item); | |
| 274 | + this[kCount]++; | ||
| 264 | 275 | this[kIndexEntry](item); | |
| 265 | 276 | } | |
| 266 | 277 | ||
| 278 | + get length() { | ||
| 279 | + return this[kCount]; | ||
| 280 | + } | ||
| 281 | + | ||
| 267 | 282 | [kIndexEntry](entry) { | |
| 268 | 283 | // Default implementation does nothing | |
| 269 | 284 | } | |
@@ -384,9 +399,22 @@ class Performance extends PerformanceObserverEntryList { | |||
| 384 | 399 | this[kIndex] = { | |
| 385 | 400 | [kMarks]: new Set() | |
| 386 | 401 | }; | |
| 402 | + this[kMaxCount] = kDefaultMaxCount; | ||
| 387 | 403 | this[kInsertEntry](nodeTiming); | |
| 388 | 404 | } | |
| 389 | 405 | ||
| 406 | + set maxEntries(val) { | ||
| 407 | + if (typeof val !== 'number' || val >>> 0 !== val) { | ||
| 408 | + const errors = lazyErrors(); | ||
| 409 | + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'val', 'number'); | ||
| 410 | + } | ||
| 411 | + this[kMaxCount] = Math.max(1, val >>> 0); | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + get maxEntries() { | ||
| 415 | + return this[kMaxCount]; | ||
| 416 | + } | ||
| 417 | + | ||
| 390 | 418 | [kIndexEntry](item) { | |
| 391 | 419 | const index = this[kIndex]; | |
| 392 | 420 | const type = item.entry.entryType; | |
@@ -397,6 +425,17 @@ class Performance extends PerformanceObserverEntryList { | |||
| 397 | 425 | } | |
| 398 | 426 | const entry = item.entry; | |
| 399 | 427 | L.append(items, { entry, item }); | |
| 428 | + const count = this[kCount]; | ||
| 429 | + if (count > this[kMaxCount]) { | ||
| 430 | + const text = count === 1 ? 'is 1 entry' : `are ${count} entries`; | ||
| 431 | + process.emitWarning('Possible perf_hooks memory leak detected. ' + | ||
| 432 | + `There ${text} in the ` + | ||
| 433 | + 'Performance Timeline. Use the clear methods ' + | ||
| 434 | + 'to remove entries that are no longer needed or ' + | ||
| 435 | + 'set performance.maxEntries equal to a higher ' + | ||
| 436 | + 'value (currently the maxEntries is ' + | ||
| 437 | + `${this[kMaxCount]}).`); | ||
| 438 | + } | ||
| 400 | 439 | } | |
| 401 | 440 | ||
| 402 | 441 | [kClearEntry](type, name) { | |
@@ -411,10 +450,12 @@ class Performance extends PerformanceObserverEntryList { | |||
| 411 | 450 | if (entry.name === `${name}`) { | |
| 412 | 451 | L.remove(item); // remove from the index | |
| 413 | 452 | L.remove(item.item); // remove from the master | |
| 453 | + this[kCount]--; | ||
| 414 | 454 | } | |
| 415 | 455 | } else { | |
| 416 | 456 | L.remove(item); // remove from the index | |
| 417 | 457 | L.remove(item.item); // remove from the master | |
| 458 | + this[kCount]--; | ||
| 418 | 459 | } | |
| 419 | 460 | item = next; | |
| 420 | 461 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,29 @@ | |||
| 1 | + // Flags: --no-warnings | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const { performance } = require('perf_hooks'); | ||
| 6 | + const assert = require('assert'); | ||
| 7 | + | ||
| 8 | + assert.strictEqual(performance.length, 1); | ||
| 9 | + assert.strictEqual(performance.maxEntries, 150); | ||
| 10 | + | ||
| 11 | + performance.maxEntries = 1; | ||
| 12 | + | ||
| 13 | + [-1, 0xffffffff + 1, '', null, undefined, Infinity].forEach((i) => { | ||
| 14 | + common.expectsError( | ||
| 15 | + () => performance.maxEntries = i, | ||
| 16 | + { | ||
| 17 | + code: 'ERR_INVALID_ARG_TYPE', | ||
| 18 | + type: TypeError | ||
| 19 | + } | ||
| 20 | + ); | ||
| 21 | + }); | ||
| 22 | + | ||
| 23 | + common.expectWarning('Warning', [ | ||
| 24 | + 'Possible perf_hooks memory leak detected. There are 2 entries in the ' + | ||
| 25 | + 'Performance Timeline. Use the clear methods to remove entries that are no ' + | ||
| 26 | + 'longer needed or set performance.maxEntries equal to a higher value ' + | ||
| 27 | + '(currently the maxEntries is 1).']); | ||
| 28 | + | ||
| 29 | + performance.mark('test'); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments