From a8c44cc9a356668c4174b5bbfc7eb4f8239b70c8 Mon Sep 17 00:00:00 2001 From: Scott Hovestadt <scotthovestadt@fb.com> Date: Thu, 28 Mar 2019 17:01:32 -0700 Subject: [PATCH 1/5] Memory leak fix: release console output reference after printed to stdout. --- packages/jest-reporters/src/default_reporter.ts | 6 +++--- packages/jest-test-result/src/helpers.ts | 2 +- packages/jest-test-result/src/types.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/jest-reporters/src/default_reporter.ts b/packages/jest-reporters/src/default_reporter.ts index 664e30d665d7..e1d886008f24 100644 --- a/packages/jest-reporters/src/default_reporter.ts +++ b/packages/jest-reporters/src/default_reporter.ts @@ -172,8 +172,7 @@ export default class DefaultReporter extends BaseReporter { result: TestResult, ) { this.log(getResultHeader(result, this._globalConfig, config)); - const consoleBuffer = result.console; - if (consoleBuffer && consoleBuffer.length) { + if (result.console) { this.log( ' ' + TITLE_BULLET + @@ -181,9 +180,10 @@ export default class DefaultReporter extends BaseReporter { getConsoleOutput( config.cwd, !!this._globalConfig.verbose, - consoleBuffer, + result.console, ), ); + result.console = undefined; } } diff --git a/packages/jest-test-result/src/helpers.ts b/packages/jest-test-result/src/helpers.ts index a46f86959945..202cd2bf6e8c 100644 --- a/packages/jest-test-result/src/helpers.ts +++ b/packages/jest-test-result/src/helpers.ts @@ -46,7 +46,7 @@ export const buildFailureTestResult = ( testPath: Config.Path, err: SerializableError, ): TestResult => ({ - console: null, + console: undefined, displayName: '', failureMessage: null, leaks: false, diff --git a/packages/jest-test-result/src/types.ts b/packages/jest-test-result/src/types.ts index b24c117d0834..99c5503fb21b 100644 --- a/packages/jest-test-result/src/types.ts +++ b/packages/jest-test-result/src/types.ts @@ -101,7 +101,7 @@ export type Suite = { }; export type TestResult = { - console?: ConsoleBuffer | null; + console?: ConsoleBuffer; coverage?: CoverageMapData; displayName?: Config.DisplayName; failureMessage?: string | null; From e788947963646c113c102d521f814e1c37b75a49 Mon Sep 17 00:00:00 2001 From: Scott Hovestadt <scotthovestadt@fb.com> Date: Thu, 28 Mar 2019 17:03:22 -0700 Subject: [PATCH 2/5] Resolve type errors. --- .../jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts | 2 +- packages/jest-console/src/CustomConsole.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index f3ba05efcddd..40f93dbf3c0b 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -196,7 +196,7 @@ export const runAndTransformResultsToJestFormat = async ({ dispatch({name: 'teardown'}); return { - console: null, + console: undefined, displayName: config.displayName, failureMessage, leaks: false, // That's legacy code, just adding it so Flow is happy. diff --git a/packages/jest-console/src/CustomConsole.ts b/packages/jest-console/src/CustomConsole.ts index 758f3f53b7ba..13bcd0e7ec23 100644 --- a/packages/jest-console/src/CustomConsole.ts +++ b/packages/jest-console/src/CustomConsole.ts @@ -141,6 +141,6 @@ export default class CustomConsole extends Console { } getBuffer() { - return null; + return undefined; } } From 4c7459076639fbd857d780667aad760d24452d1e Mon Sep 17 00:00:00 2001 From: Scott Hovestadt <scotthovestadt@fb.com> Date: Thu, 28 Mar 2019 17:08:42 -0700 Subject: [PATCH 3/5] Return undefined if no console output. --- packages/jest-console/src/BufferedConsole.ts | 4 ++-- .../src/__tests__/bufferedConsole.test.ts | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/jest-console/src/BufferedConsole.ts b/packages/jest-console/src/BufferedConsole.ts index 0a4f125d705d..a8ed338b0b01 100644 --- a/packages/jest-console/src/BufferedConsole.ts +++ b/packages/jest-console/src/BufferedConsole.ts @@ -159,7 +159,7 @@ export default class BufferedConsole extends Console { this._log('warn', format(firstArg, ...rest)); } - getBuffer(): ConsoleBuffer { - return this._buffer; + getBuffer() { + return this._buffer.length ? this._buffer : undefined; } } diff --git a/packages/jest-console/src/__tests__/bufferedConsole.test.ts b/packages/jest-console/src/__tests__/bufferedConsole.test.ts index dbd3ce39d2eb..ac6b06966b0c 100644 --- a/packages/jest-console/src/__tests__/bufferedConsole.test.ts +++ b/packages/jest-console/src/__tests__/bufferedConsole.test.ts @@ -10,11 +10,14 @@ import BufferedConsole from '../BufferedConsole'; describe('CustomConsole', () => { let _console: BufferedConsole; - const stdout = () => - _console - .getBuffer() - .map(log => log.message) - .join('\n'); + const stdout = () => { + const buffer = _console.getBuffer(); + if (!buffer) { + return ''; + } + + return buffer.map(log => log.message).join('\n'); + }; beforeEach(() => { _console = new BufferedConsole(() => null); From ccc6d298f3819df5d76a4ddfc1c78c0431aabb6a Mon Sep 17 00:00:00 2001 From: Scott Hovestadt <scotthovestadt@fb.com> Date: Thu, 28 Mar 2019 17:14:43 -0700 Subject: [PATCH 4/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ccf8f3e6c99..8fc9e0a27d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - `[jest-core]` Improve performance of SearchSource.findMatchingTests by 15% ([#8184](https://github.com/facebook/jest/pull/8184)) - `[jest-resolve]` Optimize internal cache lookup performance ([#8183](https://github.com/facebook/jest/pull/8183)) - `[jest-core]` Dramatically improve watch mode performance ([#8201](https://github.com/facebook/jest/pull/8201)) +- `[jest-console]` Fix memory leak by releasing console output reference when printed to stdout ([#8233](https://github.com/facebook/jest/pull/8233)) ## 24.5.0 From eb1d72c842d757f87911dfac15d9fa5ab3557fde Mon Sep 17 00:00:00 2001 From: Scott Hovestadt <scotthovestadt@fb.com> Date: Fri, 29 Mar 2019 08:37:17 -0700 Subject: [PATCH 5/5] Move memory release out of reporter. --- packages/jest-core/src/ReporterDispatcher.ts | 3 +++ packages/jest-reporters/src/default_reporter.ts | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/jest-core/src/ReporterDispatcher.ts b/packages/jest-core/src/ReporterDispatcher.ts index 00aa37f3f287..32102ed4751c 100644 --- a/packages/jest-core/src/ReporterDispatcher.ts +++ b/packages/jest-core/src/ReporterDispatcher.ts @@ -36,6 +36,9 @@ export default class ReporterDispatcher { reporter.onTestResult && (await reporter.onTestResult(test, testResult, results)); } + + // Release memory if unused later. + testResult.console = undefined; } async onTestStart(test: Test) { diff --git a/packages/jest-reporters/src/default_reporter.ts b/packages/jest-reporters/src/default_reporter.ts index e1d886008f24..1946f9c2a9f4 100644 --- a/packages/jest-reporters/src/default_reporter.ts +++ b/packages/jest-reporters/src/default_reporter.ts @@ -183,7 +183,6 @@ export default class DefaultReporter extends BaseReporter { result.console, ), ); - result.console = undefined; } }