-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
dart:analysis_server
takes 19GB memory
#52447
Comments
@fzyzcjy you have dart_code_metrics plugin enabled, right? The plugin API is the problem. |
If you want to check what is the difference in memory with the standalone, let me know. |
@incendial Hi thanks for the reply, but indeed no. I do not enable the dart_code_metrics plugin when using the analysis server; indeed I run dart_code_metrics separately to check lint problems. See the screenshot below (no plugins). |
Ah, my bad then, my assumption was wrong. 93 contexts though... 🥲 |
Well... I know it looks like a nontrivial number. But is that too many? I have not heard of documents saying that I should use packages as few as possible... The total number of Dart lines is at the quantity of 100kloc (e.g. 200kloc, I forget the exact numbers). There are a few packages that are huge, and many are small. |
@bwilkerson @jacob314 as an anecdotal evidence that users with many analysis contexts exist :-D |
From the screenshot you're running an old version of dart. The new version should have a "Collect Report" option at the top of the "Analysis Server Diagnostics" page which could help us diagnose this problem. (It also contains some memory optimizations so updating might even help the problem in itself). |
@jensjoha Thanks for the information! Yes I am using Flutter 3.7 (and dare not update to 3.10.0 since many people are saying it is buggy (though exciting)... so may have to wait for something like 3.10.3). I will update this post with the collected report once I upgrade. |
We've been meaning to publish something along these lines, but we don't have the data to support a number. But 93 is a lot. Our analytics are showing that the vast majority of IDE sessions are opened to less than 5 contexts. And there is (currently) a linear correlation between # of contexts and memory usage. |
@srawlins Thanks for the information! Then may I know how is this possible to only have 5 contexts? My usage is as follows (happy to provide more information when needed):
|
A separate context is created for every One way to reduce the number of contexts is to open the IDE window to a more narrowly focused directory, somewhere inside of the directory containing 93 contexts. I expect most users have only one context in their DAS instance because their IDE is open to just one Flutter app.
Can you explain a little better why so many packages are needed to support one feature?
All of the READMEs point to the first one, but I don't think the first one explains what any of the others are. Is there a page describing these different packages? In particular, I'm curious to know why a |
@srawlins Hi thanks for the reply!
I checked the name of my 93 contexts listed in
Well, I need all those packages and very frequently navigate here and there among them... So I cannot just throw away some of them inside the IDE :/
Sure!
|
Thanks for the explanation. I don't have any further advice on reducing the number of contexts in play. |
@srawlins Thank you for the reply. Then maybe this is a legitimate scenario to have this many packages. |
@srawlins how many people you need to upvote the issue to address the problem with monorepos and multiple contexts? I've spoken with too many people already that really suffer from the analyzer perf (without plugins) on a scale. I believe it's a small percentage of the overall Dart devs, but the thing is with time this number will only grow. |
A great question! Now that we have analytics, we don't need upvotes as a signal as much any more. Upvotes are still good, and analytics can't answer all the questions. This is largely a question of ROI. Some of the ideas we've thrown around are very high effort and complexity (bug-prone) and maintenance cost, in order to serve users with many analysis contexts. So we weigh that ROI against other work in the queue. One item I'd like to accomplish, which is not too complicated, is to not create new analysis contexts for each We have other ideas, and the priority is informed largely by analytics. |
@srawlins I see. But I am a bit confused and curious: I am just an (individual) developer so my codebase is quite small. There must be (a lot of) teams and groups who are using Flutter to develop apps. On the other hand, you mentioned most people have few contexts. So I guess it is either because the large teams only have small number of packages (which I do not know how... since I have explained my scenario above and it seems it is hard to be reduced), or because most people use Flutter for small apps? |
@srawlins so we basically come to a situation when people with actual performance problems can't get any attention to their problems because on a scale their problems are insignificant to you. I'm asking about numbers, because I can easily find 200+ people with the same problem as @fzyzcjy has without any effort. I understand that large codebases are locked into using the analyzer the way it works now (with no alternatives and no way to migrate off Dart / Flutter in a reasonable time), but are various hacks you suggest (like opening a subfolder) really the best option they can have in a long run? Can you also give more details how exactly this analytics is collected? Do people who open hello-worlds count? @fzyzcjy I believe it's the latter. |
CC @bwilkerson and @jacob314 for any insights and I don't know what user stories we can derive from just the analytics (it's pretty limited data), but as a hunch, I would guess that many users literally open their VS Code window to a single Flutter app, with no internal packages 🤷 . Someone posited on a different issue that ~99% of Dart developers do not write "packages" which are published to pub; they are writing Flutter apps. It would be really interesting to get analytics that help us understand that. (Most of my VS Code windows are a single analysis context but I won't claim to be a typical flutter developer by any stretch. I usually have 3-5 VS Code windows open to different packages I'm working on within a "few days" timespan, like linter, dartdoc, analyzer, markdown, mockito. I'm very happy with 3-5 VS Code windows 🤷 .)
I apologize if it feels that way. I haven't closed this issue as "Won't Fix." It's just a matter of binning into priorities. So I cannot promise a timeline for a better many-packages-in-workspace Developer Experience.
CC @bwilkerson I imagine we publish somewhere what data we collect, right? But yes, I think even hello worlds count. I'm not sure how often the data is collected for each user, which might distinguish hello world users from large app / multi-context users. |
Even a flutter app can be separated into packages. For example, if you have several apps with the same reusable core blocks (have discussed at least two cases like this).
Yep, me neither, so I can't judge from my exp, but talking to people that get no help upsets me a lot. DCM itself has 13 contexts which is fine for now (rarely get more than 1.5 GB).
They all are not in a single monorepo (and not very related to each other in terms of code changes, at least not all of them), so you basically have no options 🙂.
How to say that... considering the overall planning approach, low priority thing can become a won't fix if there is always something more important. And as I know, the number of people with many contexts is low relative to the total number in the analytics data you have. |
I work on a project with a much greater number of LoC (but less contexts at 49) and we used to have a similar issue to this, in the end our fix was to remove almost all of the barrel files. We had a lot of circular references that both slowed down analysis greatly and caused memory pressure. This also put a stop to our ambition to further split our app into more packages in our monorepo as this would further push our use of barrel files. If you have a package |
I'm not aware of anywhere that this information is published. That got me curious, so I tried to find out what Flutter documents, and the only thing I could find was information about crash reporting and how to disable analytics: https://docs.flutter.dev/reference/crash-reporting. I might have missed something, but I don't think Flutter provides that data either. That said, I can confirm that we're collecting analytics for all projects no matter how large or small, so yes, if a disproportionate number of users (that have enabled analytics) are opening small hello-world sized packages that might impact the numbers. |
Thanks, could you also please share how does it work for forks, for example? Or for projects copied from a template like it usually happens for job interviews? No differentiation? |
@incendial, we use a single barrel file per package to expose classes that are hidden under the |
Hi, I upgraded to Dart 3.0 and here is the report. (It is 16-18GB at the time I create the report, but sometimes it again becomes 19GB. I also removed and added some packages after the first post of the issue, so the number of packages will not exactly match what I said before) |
We also have many package for our project (an app), about ~120. Running all tests and codegen takes ~1h for the whole code base. So to be able to qualify pull requests in an acceptable time and to be able to run tests/codegen while developing, we split the code into packages for individual features, so we can limit test/codegen to only packages that are affected by the work you're doing. Over time, the number has grown with the number of features (and their interactions) and to avoid circular dependencies. |
Thanks @fzyzcjy! It has 40,611,996 (looking) So I seem to be able to reproduce this in Windows (though Mac seems to be the same, Linux isn't) --- with a session with now 40,434,365 |
@jensjoha Thanks for the information! A bit more context (for the zip I provided): It goes to the huge memory after using for a while (instead of being there in the first minute), so I also expect it can be some kind of leaks. |
…er 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. Change-Id: I718e8edc81b763b66affa16c3b3f6d4b8a97fd1e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308940 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
I recently enabled auto-snapshotting for analyzer, in case of memory overuse. Here is instruction how to configure it: go/analyser-memory-troubleshooting-with-auto-snapshotting |
…fterContextsCreated` is called If again and again editing, say, a `pubspec.yaml` with proper timing there is a "temporary leak" that repairs itself once the analyzer finishes (some time after the editing stops). What happens is that old contexts are saved in the `declarationsTracker` but eventually cleared in the `afterContextsCreated` call. In a test on Windows (on Linux I'd currently run into https://dartbug.com/52703) I opened the entire "pkg" folder and edited a `pubspec.yaml` file every 5 seconds. The analyzer went from using something along the lines of 700MB of heap to using around 2.5 GB of heap after 25 edits and 17GB (!) of heap shortly before stopping at 250 `pubspec.yaml` edits. After the editing stopped (and clicking the GC button in observatory) the heap usage went down to ~650MB heap used. This fixes the problem by clearing the `declarationsTracker` on the `afterContextsDestroyed` call too. In the same test it stays at around 300-700MB of heap. Possibly related to: #48788 #52447 Change-Id: Ia38cc946a1f36fa8c5b6804f79cbc8dd96c21030 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309722 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
Public document with instructions how to setup auto-snapshotting for analyzer in case of huge memory usage: https://docs.google.com/document/d/1mxCKhvyHUtGVhIH5Apx9y7V7itqCxAQPse6ghbjaDMM |
…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>
Does the issue still reproduces for you? |
@polina-c Yes and no. It is ~10GB today (though it is still quite huge, it is much better than ~19GB). I am happy to configure auto snapshotting, but before that I need to confirm - I am on stable channel, is it OK, or do I need master Flutter? |
FYI I would expect the issue to be fixed* on Flutter master --- the likely fix (5aee0f6) (and 5e08794 though that "leak" is only temporary) has landed a good while back. The fix seems to have been chery-picked in stable and landed (7475c2c) which I think means it will be included in the next stable release (though I don't know when that will be). * At least I'd expect it to get way down from 19/10 GB --- we previously saw that @fzyzcjy had lots of |
That looks great! I will wait for next stable and report the updates here. |
Auto-snapshotting is available starting Dart 3.1.0-200.0.dev. Current Flutter stable has 3.0.5. So, master has it, but stable does not yet. |
@fzyzcjy The fix was released on flutter version 3.10.6. You can give it a try to see how is the memory usage now. |
@gabrielgarciagava I will do that soon (when focusing on frontend again)! |
@fzyzcjy I'm going to close this issue as a few folks on the Dart team have landed many memory improvements in the Analyzer code bases over the last year, and even over the last six months (see below). I won't promise that your memory problems are solved, but I think at this point, it would be most effective to sort of rebase the discussion. Anyone else experiencing similar "giant memory usage" issues with the Dart Analyzer, and you'd like to document a bit your situation, also please follow these instructions: First, be sure to bump to the latest Dart, 3.2.0, as it has some performance improvements over 3.1.0. Then, if you experience what you feel is an inordinate amount of memory being used (we don't have any SLOs yet in this space, but anything north of 5GB is probably noteworthy):
Recent memory-reducing changes:Dart ~ 2.19.0, Jan 2023
Dart ~3.0.0, May 2023
Dart ~3.1.0, August 2023
Dart ~3.2.0, November 2023
(There were also speed-up improvements made in this time frame, and improvements to our analytics, logging, benchmarking, and platform coverage, but I'm not documenting those here on this memory-focused issue.) |
Thank you and the Dart team for improving this! I will try Dart 3.2 later and report if anything goes wrong. |
I faced the same problem in flutter 3.7.12 but upgrading flutter version was not a option because I have a huge code base with 3-4 big modules which I have to migrate all my modules to dart null safety, I found the solution which worked on me |
For those who still experience this, you can enable auto memory snapshotting for analyzer. Do not worry, it will not fill all you hard drive with snapshots, it will stop at the configured limit. Here is the steps how to configure your IDE to turn on analyzer autosnapshotting: https://docs.google.com/document/d/1mxCKhvyHUtGVhIH5Apx9y7V7itqCxAQPse6ghbjaDMM/edit Then, with DevTools starting flutter 3.22.0-1.0.pre.10 or fresher (you do not have to migrate your project, just switch to flutter master to get DevTools) you can import and diff the collected snapshots. |
Well, I have reported here #41793 (comment), but I am not sure whether it is more reasonable to create a new issue, since the memory size is really really a lot IMHO. The original issue complains when it takes <2GB, while here it is nearly 20GB!
The text was updated successfully, but these errors were encountered: