diff --git a/CHANGELOG.md b/CHANGELOG.md index 5866f9aad174..116c4eab7169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes +- `[jest-leak-detector]` Make leak-detector more aggressive when running GC ([#14526](https://github.com/jestjs/jest/pull/14526)) + ### Performance ### Chore & Maintenance diff --git a/packages/jest-leak-detector/src/__tests__/index.test.ts b/packages/jest-leak-detector/src/__tests__/index.test.ts index 62f9afcb2777..dd5a97dbf2bb 100644 --- a/packages/jest-leak-detector/src/__tests__/index.test.ts +++ b/packages/jest-leak-detector/src/__tests__/index.test.ts @@ -7,6 +7,11 @@ import LeakDetector from '../index'; +jest.mock('v8', () => ({ + ...(jest.requireActual('v8') as Record), + getHeapSnapshot: jest.fn(), +})); + const gc = globalThis.gc; // Some tests override the "gc" value. Let's make sure we roll it back to its diff --git a/packages/jest-leak-detector/src/index.ts b/packages/jest-leak-detector/src/index.ts index 2a4ec55b09d2..3de50dacac7b 100644 --- a/packages/jest-leak-detector/src/index.ts +++ b/packages/jest-leak-detector/src/index.ts @@ -7,7 +7,7 @@ /// import {promisify} from 'util'; -import {setFlagsFromString} from 'v8'; +import {getHeapSnapshot, setFlagsFromString} from 'v8'; import {runInNewContext} from 'vm'; import {isPrimitive} from 'jest-get-type'; import {format as prettyFormat} from 'pretty-format'; @@ -48,6 +48,17 @@ export default class LeakDetector { await tick(); } + if (this._isReferenceBeingHeld) { + // triggering a heap snapshot is more aggressive than just `global.gc()`, + // but it's also quite slow, so only do it if we still think we're leaking. + // https://github.com/nodejs/node/pull/48510#issuecomment-1719289759 + getHeapSnapshot(); + + for (let i = 0; i < 10; i++) { + await tick(); + } + } + return this._isReferenceBeingHeld; }