Skip to content

fix: hook requestWindow via prototype to avoid instantiating DocumentPictureInPicture#171

Draft
MajorLift wants to merge 1 commit into
LavaMoat:mainfrom
MajorLift:fix/pip-hook-avoid-instance-instantiation
Draft

fix: hook requestWindow via prototype to avoid instantiating DocumentPictureInPicture#171
MajorLift wants to merge 1 commit into
LavaMoat:mainfrom
MajorLift:fix/pip-hook-avoid-instance-instantiation

Conversation

@MajorLift

Copy link
Copy Markdown

Problem

hookRequest's guard reads win?.documentPictureInPicture?.requestWindow. documentPictureInPicture is a lazily instantiated WebIDL attribute, so the guard itself creates a per-window DocumentPictureInPicture instance in every window Snow protects, whether or not the API is ever used.

On Firefox, which shipped the API in Firefox 151 (May 2026), the created instance's preserved JS wrapper acts as a black GC root that the cycle collector fails to break after the window closes, pinning the closed window's entire realm (document, React tree, application state). In the MetaMask extension this retains every closed UI window: measured ~70 detached window entries (~105MB on a fresh wallet) per popup open/close on official builds, reaching 3.5GB after 30 cycles (MetaMask/metamask-extension#42891). Dev builds, which do not run Snow, retain zero under the same protocol. The onset matches Firefox 151's rollout: this hook dates to April 2023 and was dormant on Firefox until the API shipped.

The retaining path (two independent windows traced via CC/GC heap logs and find_roots.py):

DocumentPictureInPicture (C++, refcounted, 2 unknown CC edges)
  → preserved JS wrapper → shape chain → realm global (Window)
  → the entire detached document

The collection failure itself is a Gecko defect (related family: Bugzilla 1902438) and is being filed upstream separately. This change removes the instantiation regardless, which prevents the leak on current Firefox releases.

Description

This commit moves the requestWindow hook from the per-window instance to DocumentPictureInPicture.prototype, reached through the interface object, which does not invoke the instance-creating getter.

Call semantics are unchanged: instance method lookup falls through to the patched prototype, this remains the instance at call time, and the wrapped native is the same function object previously found via the instance. hookDocumentPictureInPicture already operated on interface prototypes. Behavior on browsers without the API is unchanged (the guard returns early on a missing interface object, without touching the lazy attribute).

Verification

Existing suites should pass unchanged (no behavioral difference for API users). In the MetaMask extension context, an automated probe (headless Firefox 152, official production builds, forced GC/CC before every reading) shows the leak at ~70 detached window entries per popup cycle with the instance hook; the acceptance criterion for this fix is zero net detached documents over 30 cycles on a build carrying it. Happy to share the probe and heap-log traces.

pull Bot pushed a commit to Reality2byte/metamask-extension that referenced this pull request Jul 10, 2026
…ctureInPicture` instantiation in Snow hook cp-13.39.2 (MetaMask#44352)

## **Motivation**

On Firefox, every closed MetaMask window (popup, notification, home) is
retained in memory
([MetaMask#42891](MetaMask#42891)
and recent internal reports).

- **Rate:** ~70 detached window entries (~105MB, fresh test wallet) per
popup open/close, linear with use. 30 cycles leave **3.56GB** (13.37.0)
/ **3.31GB** (13.38.1) of detached documents, surviving forced GC.
State-heavy wallets multiply every retained document.
- **Mechanism** (heap-graph traced, intervention-tested): Snow's
picture-in-picture hook reads
`win?.documentPictureInPicture?.requestWindow` in every window. The read
lazily instantiates a per-window `DocumentPictureInPicture`, and
Firefox's cycle collector fails to break the instance's
preserved-wrapper cycle after window close, pinning the entire realm.
- **Why now:** Firefox shipped the API in 151 (May 2026). The April-2023
hook was dormant until users auto-updated. The collection failure itself
is a Gecko defect (upstream filing in progress; prior art: [Bugzilla
1902438](https://bugzilla.mozilla.org/show_bug.cgi?id=1902438)), but
this fix does not depend on Mozilla.

## **Description**

Applies the upstream Snow fix
([LavaMoat/snow#171](LavaMoat/snow#171)) as a
Yarn patch: the hook moves from the per-window instance to
`DocumentPictureInPicture.prototype`, reached through the interface
object, which does not invoke the instance-creating getter.

- Call semantics unchanged: instance lookup falls through to the patched
prototype, `this` stays the instance, same wrapped native. Snow's PiP
realm monitoring is preserved.
- The patch covers `snow.prod.js` and `snow.js` in addition to
`src/request.js`: the extension consumes Snow's prebuilt bundle as a
LavaMoat static shim (`LavamoatPlugin`), and webpack never processes
`@lavamoat/snow/**`.
- **Interim:** remove this patch when `@lavamoat/snow` is bumped to a
release containing the upstream fix. The bump is the removal trigger.

## **Cherry-pick candidacy**

- Affected population: every Firefox user on 151+ (effectively the whole
Firefox base via auto-update). Reproduces from a fresh wallet in five
popup opens. No workaround short of a browser restart.
- Proposed: next RC, with a hotfix on the current production line worth
considering.
- Snow is security-team-owned. Their sign-off on shipping a patched Snow
is part of this review.

## **Verification**

| Check | Result |
|---|---|
| Intervention: official 13.37.0 artifact, only this hook changed, 30
cycles | **+2,100 docs (3.35GB) → -13 (1.6MB total)**. Hook is the sole
delta, so this is also the causal proof |
| This PR's CI artifact (`d4dd55f`), probed directly | Patched hook
present; 5 cycles: +7 KB-scale entries (1.1MB) vs +345 docs (+534MB)
stock |
| Field | Original reporter confirms the leak is gone on this PR's CI
build |
| Independent repro | Manual steps + automated probe:
https://github.com/MajorLift/snow/tree/verification/pip-realm-leak/verification
|

## **Related issues**

Fixes: MetaMask#42891

## **Manual testing steps**

1. Install this PR's Firefox build (metamaskbot comment) in a fresh
profile via `about:debugging` → Load Temporary Add-on. Onboard with a
test SRP.
2. Confirm the fix is live: extension console →
`DocumentPictureInPicture.prototype.requestWindow.name` → `"open"`
(stock: `"requestWindow"`).
3. Open/close the popup five times, visiting activity or a swap view on
a few opens.
4. `about:memory` → Minimize memory usage → Measure → filter `detached`:
no `moz-extension` UI-document cohorts (stock: ~70 entries / ~105MB per
cycle).

## **Screenshots/Recordings**

Heap-graph traces, memory reports, and retaining-path analysis: see the
verification bundle above.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

CHANGELOG entry: Fixed a memory leak on Firefox where closed MetaMask
windows were retained in memory, growing extension memory use with every
popup open
runway-github Bot added a commit to MetaMask/metamask-extension that referenced this pull request Jul 13, 2026
…entPictureInPicture` instantiation in Snow hook cp-13.39.2 (#44352)

## **Motivation**

On Firefox, every closed MetaMask window (popup, notification, home) is
retained in memory
([#42891](#42891)
and recent internal reports).

- **Rate:** ~70 detached window entries (~105MB, fresh test wallet) per
popup open/close, linear with use. 30 cycles leave **3.56GB** (13.37.0)
/ **3.31GB** (13.38.1) of detached documents, surviving forced GC.
State-heavy wallets multiply every retained document.
- **Mechanism** (heap-graph traced, intervention-tested): Snow's
picture-in-picture hook reads
`win?.documentPictureInPicture?.requestWindow` in every window. The read
lazily instantiates a per-window `DocumentPictureInPicture`, and
Firefox's cycle collector fails to break the instance's
preserved-wrapper cycle after window close, pinning the entire realm.
- **Why now:** Firefox shipped the API in 151 (May 2026). The April-2023
hook was dormant until users auto-updated. The collection failure itself
is a Gecko defect (upstream filing in progress; prior art: [Bugzilla
1902438](https://bugzilla.mozilla.org/show_bug.cgi?id=1902438)), but
this fix does not depend on Mozilla.

## **Description**

Applies the upstream Snow fix
([LavaMoat/snow#171](LavaMoat/snow#171)) as a
Yarn patch: the hook moves from the per-window instance to
`DocumentPictureInPicture.prototype`, reached through the interface
object, which does not invoke the instance-creating getter.

- Call semantics unchanged: instance lookup falls through to the patched
prototype, `this` stays the instance, same wrapped native. Snow's PiP
realm monitoring is preserved.
- The patch covers `snow.prod.js` and `snow.js` in addition to
`src/request.js`: the extension consumes Snow's prebuilt bundle as a
LavaMoat static shim (`LavamoatPlugin`), and webpack never processes
`@lavamoat/snow/**`.
- **Interim:** remove this patch when `@lavamoat/snow` is bumped to a
release containing the upstream fix. The bump is the removal trigger.

## **Cherry-pick candidacy**

- Affected population: every Firefox user on 151+ (effectively the whole
Firefox base via auto-update). Reproduces from a fresh wallet in five
popup opens. No workaround short of a browser restart.
- Proposed: next RC, with a hotfix on the current production line worth
considering.
- Snow is security-team-owned. Their sign-off on shipping a patched Snow
is part of this review.

## **Verification**

| Check | Result |
|---|---|
| Intervention: official 13.37.0 artifact, only this hook changed, 30
cycles | **+2,100 docs (3.35GB) → -13 (1.6MB total)**. Hook is the sole
delta, so this is also the causal proof |
| This PR's CI artifact (`d4dd55f`), probed directly | Patched hook
present; 5 cycles: +7 KB-scale entries (1.1MB) vs +345 docs (+534MB)
stock |
| Field | Original reporter confirms the leak is gone on this PR's CI
build |
| Independent repro | Manual steps + automated probe:
https://github.com/MajorLift/snow/tree/verification/pip-realm-leak/verification
|

## **Related issues**

Fixes: #42891

## **Manual testing steps**

1. Install this PR's Firefox build (metamaskbot comment) in a fresh
profile via `about:debugging` → Load Temporary Add-on. Onboard with a
test SRP.
2. Confirm the fix is live: extension console →
`DocumentPictureInPicture.prototype.requestWindow.name` → `"open"`
(stock: `"requestWindow"`).
3. Open/close the popup five times, visiting activity or a swap view on
a few opens.
4. `about:memory` → Minimize memory usage → Measure → filter `detached`:
no `moz-extension` UI-document cohorts (stock: ~70 entries / ~105MB per
cycle).

## **Screenshots/Recordings**

Heap-graph traces, memory reports, and retaining-path analysis: see the
verification bundle above.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

CHANGELOG entry: Fixed a memory leak on Firefox where closed MetaMask
windows were retained in memory, growing extension memory use with every
popup open
runway-github Bot added a commit to MetaMask/metamask-extension that referenced this pull request Jul 13, 2026
…entPictureInPicture` instantiation in Snow hook cp-13.39.2 (#44352)

## **Motivation**

On Firefox, every closed MetaMask window (popup, notification, home) is
retained in memory
([#42891](#42891)
and recent internal reports).

- **Rate:** ~70 detached window entries (~105MB, fresh test wallet) per
popup open/close, linear with use. 30 cycles leave **3.56GB** (13.37.0)
/ **3.31GB** (13.38.1) of detached documents, surviving forced GC.
State-heavy wallets multiply every retained document.
- **Mechanism** (heap-graph traced, intervention-tested): Snow's
picture-in-picture hook reads
`win?.documentPictureInPicture?.requestWindow` in every window. The read
lazily instantiates a per-window `DocumentPictureInPicture`, and
Firefox's cycle collector fails to break the instance's
preserved-wrapper cycle after window close, pinning the entire realm.
- **Why now:** Firefox shipped the API in 151 (May 2026). The April-2023
hook was dormant until users auto-updated. The collection failure itself
is a Gecko defect (upstream filing in progress; prior art: [Bugzilla
1902438](https://bugzilla.mozilla.org/show_bug.cgi?id=1902438)), but
this fix does not depend on Mozilla.

## **Description**

Applies the upstream Snow fix
([LavaMoat/snow#171](LavaMoat/snow#171)) as a
Yarn patch: the hook moves from the per-window instance to
`DocumentPictureInPicture.prototype`, reached through the interface
object, which does not invoke the instance-creating getter.

- Call semantics unchanged: instance lookup falls through to the patched
prototype, `this` stays the instance, same wrapped native. Snow's PiP
realm monitoring is preserved.
- The patch covers `snow.prod.js` and `snow.js` in addition to
`src/request.js`: the extension consumes Snow's prebuilt bundle as a
LavaMoat static shim (`LavamoatPlugin`), and webpack never processes
`@lavamoat/snow/**`.
- **Interim:** remove this patch when `@lavamoat/snow` is bumped to a
release containing the upstream fix. The bump is the removal trigger.

## **Cherry-pick candidacy**

- Affected population: every Firefox user on 151+ (effectively the whole
Firefox base via auto-update). Reproduces from a fresh wallet in five
popup opens. No workaround short of a browser restart.
- Proposed: next RC, with a hotfix on the current production line worth
considering.
- Snow is security-team-owned. Their sign-off on shipping a patched Snow
is part of this review.

## **Verification**

| Check | Result |
|---|---|
| Intervention: official 13.37.0 artifact, only this hook changed, 30
cycles | **+2,100 docs (3.35GB) → -13 (1.6MB total)**. Hook is the sole
delta, so this is also the causal proof |
| This PR's CI artifact (`d4dd55f`), probed directly | Patched hook
present; 5 cycles: +7 KB-scale entries (1.1MB) vs +345 docs (+534MB)
stock |
| Field | Original reporter confirms the leak is gone on this PR's CI
build |
| Independent repro | Manual steps + automated probe:
https://github.com/MajorLift/snow/tree/verification/pip-realm-leak/verification
|

## **Related issues**

Fixes: #42891

## **Manual testing steps**

1. Install this PR's Firefox build (metamaskbot comment) in a fresh
profile via `about:debugging` → Load Temporary Add-on. Onboard with a
test SRP.
2. Confirm the fix is live: extension console →
`DocumentPictureInPicture.prototype.requestWindow.name` → `"open"`
(stock: `"requestWindow"`).
3. Open/close the popup five times, visiting activity or a swap view on
a few opens.
4. `about:memory` → Minimize memory usage → Measure → filter `detached`:
no `moz-extension` UI-document cohorts (stock: ~70 entries / ~105MB per
cycle).

## **Screenshots/Recordings**

Heap-graph traces, memory reports, and retaining-path analysis: see the
verification bundle above.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

CHANGELOG entry: Fixed a memory leak on Firefox where closed MetaMask
windows were retained in memory, growing extension memory use with every
popup open
runway-github Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Jul 13, 2026
… leak by avoiding `DocumentPictureInPicture` instantiation in Snow hook cp-13.39.2 (#44352)

## **Motivation**

On Firefox, every closed MetaMask window (popup, notification, home) is
retained in memory
([#42891](#42891)
and recent internal reports).

- **Rate:** ~70 detached window entries (~105MB, fresh test wallet) per
popup open/close, linear with use. 30 cycles leave **3.56GB** (13.37.0)
/ **3.31GB** (13.38.1) of detached documents, surviving forced GC.
State-heavy wallets multiply every retained document.
- **Mechanism** (heap-graph traced, intervention-tested): Snow's
picture-in-picture hook reads
`win?.documentPictureInPicture?.requestWindow` in every window. The read
lazily instantiates a per-window `DocumentPictureInPicture`, and
Firefox's cycle collector fails to break the instance's
preserved-wrapper cycle after window close, pinning the entire realm.
- **Why now:** Firefox shipped the API in 151 (May 2026). The April-2023
hook was dormant until users auto-updated. The collection failure itself
is a Gecko defect (upstream filing in progress; prior art: [Bugzilla
1902438](https://bugzilla.mozilla.org/show_bug.cgi?id=1902438)), but
this fix does not depend on Mozilla.

## **Description**

Applies the upstream Snow fix
([LavaMoat/snow#171](LavaMoat/snow#171)) as a
Yarn patch: the hook moves from the per-window instance to
`DocumentPictureInPicture.prototype`, reached through the interface
object, which does not invoke the instance-creating getter.

- Call semantics unchanged: instance lookup falls through to the patched
prototype, `this` stays the instance, same wrapped native. Snow's PiP
realm monitoring is preserved.
- The patch covers `snow.prod.js` and `snow.js` in addition to
`src/request.js`: the extension consumes Snow's prebuilt bundle as a
LavaMoat static shim (`LavamoatPlugin`), and webpack never processes
`@lavamoat/snow/**`.
- **Interim:** remove this patch when `@lavamoat/snow` is bumped to a
release containing the upstream fix. The bump is the removal trigger.

## **Cherry-pick candidacy**

- Affected population: every Firefox user on 151+ (effectively the whole
Firefox base via auto-update). Reproduces from a fresh wallet in five
popup opens. No workaround short of a browser restart.
- Proposed: next RC, with a hotfix on the current production line worth
considering.
- Snow is security-team-owned. Their sign-off on shipping a patched Snow
is part of this review.

## **Verification**

| Check | Result |
|---|---|
| Intervention: official 13.37.0 artifact, only this hook changed, 30
cycles | **+2,100 docs (3.35GB) → -13 (1.6MB total)**. Hook is the sole
delta, so this is also the causal proof |
| This PR's CI artifact (`d4dd55f`), probed directly | Patched hook
present; 5 cycles: +7 KB-scale entries (1.1MB) vs +345 docs (+534MB)
stock |
| Field | Original reporter confirms the leak is gone on this PR's CI
build |
| Independent repro | Manual steps + automated probe:
https://github.com/MajorLift/snow/tree/verification/pip-realm-leak/verification
|

## **Related issues**

Fixes: #42891

## **Manual testing steps**

1. Install this PR's Firefox build (metamaskbot comment) in a fresh
profile via `about:debugging` → Load Temporary Add-on. Onboard with a
test SRP.
2. Confirm the fix is live: extension console →
`DocumentPictureInPicture.prototype.requestWindow.name` → `"open"`
(stock: `"requestWindow"`).
3. Open/close the popup five times, visiting activity or a swap view on
a few opens.
4. `about:memory` → Minimize memory usage → Measure → filter `detached`:
no `moz-extension` UI-document cohorts (stock: ~70 entries / ~105MB per
cycle).

## **Screenshots/Recordings**

Heap-graph traces, memory reports, and retaining-path analysis: see the
verification bundle above.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

CHANGELOG entry: Fixed a memory leak on Firefox where closed MetaMask
windows were retained in memory, growing extension memory use with every
popup open
Gudahtt pushed a commit to MetaMask/metamask-extension that referenced this pull request Jul 13, 2026
… leak by avoiding `DocumentPictureInPicture` instantiation in Snow hook cp-13.39.2 (#44401)

- fix: Fix Firefox detatched-window memory leak by avoiding
`DocumentPictureInPicture` instantiation in Snow hook cp-13.39.2
(#44352)

## **Motivation**

On Firefox, every closed MetaMask window (popup, notification, home) is
retained in memory
([#42891](#42891)
and recent internal reports).

- **Rate:** ~70 detached window entries (~105MB, fresh test wallet) per
popup open/close, linear with use. 30 cycles leave **3.56GB** (13.37.0)
/ **3.31GB** (13.38.1) of detached documents, surviving forced GC.
State-heavy wallets multiply every retained document.
- **Mechanism** (heap-graph traced, intervention-tested): Snow's
picture-in-picture hook reads
`win?.documentPictureInPicture?.requestWindow` in every window. The read
lazily instantiates a per-window `DocumentPictureInPicture`, and
Firefox's cycle collector fails to break the instance's
preserved-wrapper cycle after window close, pinning the entire realm.
- **Why now:** Firefox shipped the API in 151 (May 2026). The April-2023
hook was dormant until users auto-updated. The collection failure itself
is a Gecko defect (upstream filing in progress; prior art: [Bugzilla
1902438](https://bugzilla.mozilla.org/show_bug.cgi?id=1902438)), but
this fix does not depend on Mozilla.

## **Description**

Applies the upstream Snow fix
([LavaMoat/snow#171](LavaMoat/snow#171)) as a
Yarn patch: the hook moves from the per-window instance to
`DocumentPictureInPicture.prototype`, reached through the interface
object, which does not invoke the instance-creating getter.

- Call semantics unchanged: instance lookup falls through to the patched
prototype, `this` stays the instance, same wrapped native. Snow's PiP
realm monitoring is preserved.
- The patch covers `snow.prod.js` and `snow.js` in addition to
`src/request.js`: the extension consumes Snow's prebuilt bundle as a
LavaMoat static shim (`LavamoatPlugin`), and webpack never processes
`@lavamoat/snow/**`.
- **Interim:** remove this patch when `@lavamoat/snow` is bumped to a
release containing the upstream fix. The bump is the removal trigger.

## **Cherry-pick candidacy**

- Affected population: every Firefox user on 151+ (effectively the whole
Firefox base via auto-update). Reproduces from a fresh wallet in five
popup opens. No workaround short of a browser restart.
- Proposed: next RC, with a hotfix on the current production line worth
considering.
- Snow is security-team-owned. Their sign-off on shipping a patched Snow
is part of this review.

## **Verification**

| Check | Result |
|---|---|
| Intervention: official 13.37.0 artifact, only this hook changed, 30
cycles | **+2,100 docs (3.35GB) → -13 (1.6MB total)**. Hook is the sole
delta, so this is also the causal proof |
| This PR's CI artifact (`d4dd55f`), probed directly | Patched hook
present; 5 cycles: +7 KB-scale entries (1.1MB) vs +345 docs (+534MB)
stock |
| Field | Original reporter confirms the leak is gone on this PR's CI
build |
| Independent repro | Manual steps + automated probe:

https://github.com/MajorLift/snow/tree/verification/pip-realm-leak/verification
|

## **Related issues**

Fixes: #42891

## **Manual testing steps**

1. Install this PR's Firefox build (metamaskbot comment) in a fresh
profile via `about:debugging` → Load Temporary Add-on. Onboard with a
test SRP.
2. Confirm the fix is live: extension console →
`DocumentPictureInPicture.prototype.requestWindow.name` → `"open"`
(stock: `"requestWindow"`).
3. Open/close the popup five times, visiting activity or a swap view on
a few opens.
4. `about:memory` → Minimize memory usage → Measure → filter `detached`:
no `moz-extension` UI-document cohorts (stock: ~70 entries / ~105MB per
cycle).

## **Screenshots/Recordings**

Heap-graph traces, memory reports, and retaining-path analysis: see the
verification bundle above.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding

Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

CHANGELOG entry: Fixed a memory leak on Firefox where closed MetaMask
windows were retained in memory, growing extension memory use with every
popup open
[942441b](942441b)

Co-authored-by: Jongsun Suh <jongsun.suh@icloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant