Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(core): avoid storing LView in __ngContext__ #41908

Closed
wants to merge 1 commit into from

Conversation

crisbeto
Copy link
Member

These changes combine #41358 and #41894.

Currently we save a reference to an LView on most DOM nodes created by Angular either by saving the LView directly in the __ngContext__ or by saving the LContext which has a reference to the LView. This can be a problem if the DOM node is retained in memory, because the LView has references to all of the child nodes of the view, as well as other internal data structures.

Previously we tried to resolve the issue by clearing the __ngContext__ when a node is removed (see #36011), but we decided not to proceeed, because it can slow down destruction due to a megamorphic write.

These changes aim to address the issue while reducing the performance impact by assigning a unique ID when an LView is created and adding it to __ngContext__. All active views are tracked in a map where their unique ID is used as the key. We don't need to worry about leaks within that map, because LViews are an internal data structure and we have complete control over when they are created and destroyed.

Fixes #41047.

These changes combine angular#41358 and angular#41894.

Currently we save a reference to an `LView` on most DOM nodes created by Angular either by saving the `LView` directly in the `__ngContext__` or by saving the `LContext` which has a reference to the `LView`. This can be a problem if the DOM node is retained in memory, because the `LView` has references to all of the child nodes of the view, as well as other internal data structures.

Previously we tried to resolve the issue by clearing the `__ngContext__` when a node is removed (see angular#36011), but we decided not to proceeed, because it can slow down destruction due to a megamorphic write.

These changes aim to address the issue while reducing the performance impact by assigning a unique ID when an `LView` is created and adding it to `__ngContext__`. All active views are tracked in a map where their unique ID is used as the key. We don't need to worry about leaks within that map,  because `LView`s are an internal data structure and we have complete control over when they are  created and destroyed.

Fixes angular#41047.
@google-cla google-cla bot added the cla: yes label Apr 30, 2021
@crisbeto crisbeto marked this pull request as ready for review April 30, 2021 21:47
@pullapprove pullapprove bot requested a review from mhevery April 30, 2021 21:47
@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer state: blocked target: rc This PR is targeted for the next release-candidate labels Apr 30, 2021
@AndrewKushnir AndrewKushnir self-requested a review April 30, 2021 22:15
@AndrewKushnir AndrewKushnir self-assigned this Apr 30, 2021
@AndrewKushnir
Copy link
Contributor

AndrewKushnir commented Apr 30, 2021

Presubmit + Global Presubmit.

@AndrewKushnir AndrewKushnir added the action: presubmit The PR is in need of a google3 presubmit label Apr 30, 2021
import {ID, LView} from './view';

// Keeps track of the currently-active LViews.
const TRACKED_LVIEWS = new Map<number, LView>();
Copy link
Contributor

@sod sod May 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test for memory leaks in ssr context? We ran rc.1 which included #41358 and this Map filled up rather quickly with DOM nodes, crashing the server through out of memory in a matter of seconds.

That this is stil a single Map for multiple apps rendering on one global scope makes me rather nervous.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ended up reverting the original commit due to the memory leak and the fact that fixing the leak revealed some other issues. The reverted code will be in rc.2.

These changes include the original fix plus a fix for the memory leak so that we can debug the issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sod, thanks for testing an RC version and sharing the feedback 👍

As Kristiyan mentioned, the previous version of this change was reverted and this PR has the necessary fixes to make sure the memory leak doesn't happen. If you get a chance, it's be great if you could try to use the following package (based on the changes in this PR) in your package.json file (while keeping other packages at rc.1 version):

...
"@angular/core": "https://978551-24195339-gh.circle-artifacts.com/0/angular/core-pr41908-dc11acb763.tgz",
...

and let us know if the memory leak that you've observed is resolved.

Thank you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, with https://978551-24195339-gh.circle-artifacts.com/0/angular/core-pr41908-dc11acb763.tgz memory consumption is stable. After 1000 requests the memory footprint is the same. And comparing memory heap dumps, I see no angular or dominos specific retention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sod thanks for checking! 👍

@AndrewKushnir
Copy link
Contributor

Global Presubmit #2.

@AndrewKushnir AndrewKushnir added this to the v13-candidates milestone May 6, 2021
@ngbot ngbot bot removed this from the v13-candidates milestone May 6, 2021
@AndrewKushnir AndrewKushnir added this to the v13-candidates milestone May 6, 2021
@ngbot ngbot bot removed this from the v13-candidates milestone May 6, 2021
@ngbot ngbot bot added this to the Backlog milestone May 6, 2021
@AndrewKushnir AndrewKushnir modified the milestones: Backlog, v13-candidates May 6, 2021
@AndrewKushnir AndrewKushnir added area: core Issues related to the framework runtime engine: ivy breaking changes and removed action: presubmit The PR is in need of a google3 presubmit action: review The PR is still awaiting reviews from at least one requested reviewer labels May 6, 2021
@crisbeto crisbeto closed this May 10, 2021
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime area: performance breaking changes cla: yes state: blocked target: rc This PR is targeted for the next release-candidate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

__ngContext__ magnifies native Chrome memory leaks
3 participants