Skip to content

Commit

Permalink
fix memory leaks caused by closures in jest-worker
Browse files Browse the repository at this point in the history
  • Loading branch information
shuding committed Mar 12, 2021
1 parent f73d5f6 commit bff801c
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions packages/jest-worker/src/Farm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,14 @@ export default class Farm {
};

const promise: PromiseWithCustomMessage<unknown> = new Promise(
(resolve, reject) => {
// Bind args to this function so it won't reference to the parent scope.
// This prevents a memory leak in v8, because otherwise the function will
// retaine args for the closure.
((
args: Array<unknown>,
resolve: null | ((value: unknown) => void),
reject: null | ((reason?: any) => void),
) => {
const computeWorkerKey = this._computeWorkerKey;
const request: ChildMessage = [CHILD_MESSAGE_CALL, false, method, args];

Expand All @@ -87,10 +94,14 @@ export default class Farm {
const onEnd: OnEnd = (error: Error | null, result: unknown) => {
customMessageListeners.clear();
if (error) {
reject(error);
reject?.(error);
} else {
resolve(result);
resolve?.(result);
}

// Delete reference to the Promise so its result can be garbage
// collected after calling this method.
reject = resolve = null;
};

const task = {onCustomMessage, onEnd, onStart, request};
Expand All @@ -101,7 +112,7 @@ export default class Farm {
} else {
this._push(task);
}
},
}).bind(null, args),
);

promise.UNSTABLE_onCustomMessage = addCustomMessageListener;
Expand All @@ -124,8 +135,12 @@ export default class Farm {
throw new Error('Queue implementation returned processed task');
}

// Reference the task object outside so it won't be retained by onEnd,
// and other properties of the task object, such as task.request can be
// garbage collected.
const taskOnEnd = task.onEnd;
const onEnd = (error: Error | null, result: unknown) => {
task.onEnd(error, result);
taskOnEnd(error, result);

this._unlock(workerId);
this._process(workerId);
Expand Down

0 comments on commit bff801c

Please sign in to comment.