From 5aee0f61b6301099bb25a36d2b2ff197541d3c5b Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Tue, 13 Jun 2023 14:32:49 +0000 Subject: [PATCH] [analyzer] Clear watcher subscriptions to avoid leaking package: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 https://github.com/dart-lang/sdk/issues/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. Change-Id: I718e8edc81b763b66affa16c3b3f6d4b8a97fd1e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308940 Reviewed-by: Konstantin Shcheglov Reviewed-by: Brian Wilkerson Commit-Queue: Jens Johansen --- pkg/analysis_server/lib/src/context_manager.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart index cb5b353437af..69355e3d6e31 100644 --- a/pkg/analysis_server/lib/src/context_manager.dart +++ b/pkg/analysis_server/lib/src/context_manager.dart @@ -734,11 +734,13 @@ class ContextManagerImpl implements ContextManager { } Future _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); }