Skip to content

Commit

Permalink
[stable] [analyzer] Clear watcher subscriptions to avoid leaking pack…
Browse files Browse the repository at this point in the history
…age:watcher data

Analyzer adds watchers to all root folders it has opened.
When editing, say, a pubspec.yaml file it ~starts over, cancels the
old subscriptions and creates new ones. It keeps references to the old
subscriptions too though.

This in turn leaks data.

On Linux internally in package:watcher it clears some stuff as it's
cancelled, but it doesn't on Windows, nor on Mac.

The means it can leak an infinite amount of `_Entry` classes,
and for instance in #52447 a
user has 40+ million of those classes.

Reproducing this I got to 40+ million too, at which point the
"Retained size" of all the `_Entry` objects was 7.39GB.

This fixes the leak by clearing the list.

Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/308940
Change-Id: I8a4bdbc97259bd8e13209909769330ca6d81b2a5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311466
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
srawlins authored and Commit Queue committed Jul 10, 2023
1 parent f15026d commit 7475c2c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ This is a patch release that:

- Fixes a flow in flow analysis that causes it to sometimes ignore destructuring
assignments (issue [#52767]).
- Fixes a memory leak in Dart analyzer's file-watching (issue [#52791]).

[#52767]: https://github.com/dart-lang/sdk/issues/52767
[#52791]: https://github.com/dart-lang/sdk/issues/52791

## 3.0.5 - 2023-06-14

Expand Down
8 changes: 5 additions & 3 deletions pkg/analysis_server/lib/src/context_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -643,11 +643,13 @@ class ContextManagerImpl implements ContextManager {
}

Future<void> _destroyAnalysisContexts() async {
for (final subscription in watcherSubscriptions) {
await subscription.cancel();
}
watcherSubscriptions.clear();

final collection = _collection;
if (collection != null) {
for (final subscription in watcherSubscriptions) {
await subscription.cancel();
}
for (final analysisContext in collection.contexts) {
_destroyAnalysisContext(analysisContext);
}
Expand Down

0 comments on commit 7475c2c

Please sign in to comment.