diff --git a/CHANGELOG.md b/CHANGELOG.md index 37191ffdcc36..0cc18fc14391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixes - `[jest-haste-map]` [**BREAKING**] Replaced internal data structures to improve performance ([#6960](https://github.com/facebook/jest/pull/6960)) +- `[jest-jasmine2]` Fix memory leak in Error objects hold by the framework ([#6965](https://github.com/facebook/jest/pull/6965)) ### Chore & Maintenance diff --git a/packages/jest-jasmine2/src/jasmine/Spec.js b/packages/jest-jasmine2/src/jasmine/Spec.js index e9016b7e9fb0..807c3c168f75 100644 --- a/packages/jest-jasmine2/src/jasmine/Spec.js +++ b/packages/jest-jasmine2/src/jasmine/Spec.js @@ -66,6 +66,12 @@ export default function Spec(attrs: Object) { this.initError = new Error(); this.initError.name = ''; + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + this.initError.stack = this.initError.stack; + this.queueableFn.initError = this.initError; this.result = { diff --git a/packages/jest-jasmine2/src/jasmine_async.js b/packages/jest-jasmine2/src/jasmine_async.js index d7bb10c481b0..1eaf0a8f2a4f 100644 --- a/packages/jest-jasmine2/src/jasmine_async.js +++ b/packages/jest-jasmine2/src/jasmine_async.js @@ -37,6 +37,12 @@ function promisifyLifeCycleFunction(originalFn, env) { const extraError = new Error(); + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + extraError.stack = extraError.stack; + // We make *all* functions async and run `done` right away if they // didn't return a promise. const asyncJestLifecycle = function(done) { @@ -79,6 +85,12 @@ function promisifyIt(originalFn, env) { const extraError = new Error(); + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + extraError.stack = extraError.stack; + const asyncJestTest = function(done) { const wrappedFn = isGeneratorFn(fn) ? co.wrap(fn) : fn; const returnValue = wrappedFn.call({}); diff --git a/packages/jest-jasmine2/src/queue_runner.js b/packages/jest-jasmine2/src/queue_runner.js index 5155a43374ef..d72ec1bfabbd 100644 --- a/packages/jest-jasmine2/src/queue_runner.js +++ b/packages/jest-jasmine2/src/queue_runner.js @@ -73,6 +73,7 @@ export default function queueRunner(options: Options) { 'Timeout - Async callback was not invoked within the ' + timeoutMs + 'ms timeout specified by jest.setTimeout.'; + initError.stack = initError.message + initError.stack; options.onException(initError); }, );