-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Why does Rust Analyzer use so much RAM and CPU? #11325
Comments
There's a lot to unpack here, but does it really use CPU on your system while you're not typing? |
I'm not sure why it uses the cpu when doing nothing, but the high memory usage is because it caches information to avoid having to recompute it after every keystroke which would be very much noticable. By the way are you on windows? If so is it completely using 100% of a single core (which could be ~20% of all cores depending on the amount of cores) or 20% of a single core? Task manager reports the percentage of all cores that is used, unlike linux and macos which report the percentage of a single core with full usage of two cores resulting in 200%. If it is 100% of a single core, it may be a hang in for example chalk (this happened in the past). Is this https://github.com/mankinskin/graph_app? I just tried |
That also includes the CPU usage of VS Code itself, which isn't trivial. On my system, Electron apps still use some CPU.
You can disable that with
Because it runs
With cache warm-up disabled, the starting memory usage on the RA repo itself is 154 MB. It goes up to 605 MB with cache warm-up enabled. From what I've seen, it doesn't go much past 1 GB, and this is on a pretty large codebase, 226 KLOC without dependencies, according to And there's a nifty
For example, Some of these queries could go away, at the cost of performance. We don't want to recompute the types and inlay hints, or to re-expand the macros in a file just because you've added a line at the top. A batch compiler like Of course, the memory usage could still be improved, but there's no magic optimization that would cut it in half. And having said that, how much memory would you expect it to use on a 226 KLOC project? How much does the compiler use? Or IntelliJ on a similarly-sized project? Or clangd, or Visual Studio. |
Rust-analyzer uses
Apart from the |
In addition to what the others wrote, the way that macros and name resolution in Rust work together means that all macros outside of item bodies in a crate need to be expanded to resolve any names. So while you may indeed not reference 90% of that code, it still needs to be expanded to determine that. And that's mainly what the "indexing" step actually does. (Also, dependencies need to be expanded so they're available for autoimports.) |
How can I run these commands from vs code? I can't seem to find it in the user manual.
Isn't this a whole lot of redundancy? Seems like we are storing the same things at least 3 times here. That would of course impact loadup times because more memory needs to be allocated and the disk might be read repeatedly.
Actually less than the actual code. We just need to store public signatures that are actually accessible from our current crate or even module. Also we could compress repeated identifiers quite easily. Sure the indexing structure also takes some extra space, but 226 KLOC is roughly 2MB-3MB (comparing here to a project of 170KLOC and 1.3MB), so 1GB seems like a very expensive indexing structure. What is all this memory used for? As a more immediate improvement, more control of when rust analyzer executes jobs would make using it much more pleasant. RA is very "greedy" right now, so even when I don't need it at the moment, it might force an update which may download, index dependencies, rebuild the entire project and so on. I think there should be an opt-in safety latch in addition to the "check on save" option, which prevents RA from doing more than a quick "cargo check" after saving i.e. it should detect if dependencies need to be fetched, anything needs to be indexed or whether anything needs to be compiled to run cargo check. Cargo check should not take more than 2 seconds on basically all projects, because it should really only check the local crate. But when it can't, it instantly occupies my entire system to fetch and index all dependencies for a relatively long time, which can be really annoying. For example, I usually build the project from the terminal in vscode. When I open a new project, rust analyzer may not have any index for it yet. When I make one change and save, rust analyzer wants to run check, realizes it needs to index, and I have to wait for a straight minute sometimes before I can proceed. Then, because rust analyzer doesn't share its resources with the current workspace, I still need to run my "own" Even just when opening a project rust analyzer may randomly decide to index the project even without saving a file. If RA has to make such heavy calls, it would be nice if it were more responsible with calling them. So using RA basically forces me to build the project twice at the current state. It would be nice to get a message "update metadata?" if dependencies would need to be fetched or the internal index is not quick to build, especially after just opening a project and not doing anything else. For people who don't care about this, or have beefy machines, fast internet and don't notice the overhead, they can disable asking before doing downloads or indexing, so they get the current behavior. But for people with less system resources like me and also for very large projects this seems to be a good and quick solution. |
auto-imports = quick fix feature right? So that makes sense but it still would only need to index the signatures of public items in crates my crate is directly depending on, or crates being re-exported by direct dependencies. This is never in the realms of 1GB on the projects I have been working on. |
It may still be useful to store crate indexes on disk to reuse them for the next session instead of rebuilding them every time. |
Press
It's controlled redundancy. The file source code is needed because we don't want to hit the disk e.g. during completion, and for a more subtle reason, too: it might change while we're processing a request.
That's exactly what we do, and it takes some 10s of MB for the whole project.
No. An AST will take more memory than the source code, because it's a tree and it needs to represent relationships between the nodes. And that's just the AST. We compute much more, as I said: types, macro expansion results and so on. We have to store these in such a way that typing in a file doesn't invalidate everything.
226 KLOC without the transitive dependencies, and
The
I does nothing more than a
RA doesn't do anything else besides "a quick
The "index" is not what you think, and you can disable it using the preference I mentioned above. Or if you don't, you don't need to wait until
That should only happen if you change
No, it doesn't. If you run It would be nice to get a message "update metadata?" if dependencies would need to be fetched or the internal index is not quick to build, especially after just opening a project and not doing anything else.
rust-analyzer can't work without the source code of the dependencies. We get this information from
Sure, but that's very hard to implement, and there are some good reasons not to: #4712. |
Determining those requires doing the same for their dependencies, and so on. That's information that could be thrown away afterwards, especially once we have persistent caches, sure, but that's not trivial to manage and we've had other priorities so far. |
I don't think there's anything actionable in this ticket (it would really have been better asked in the forums in the first place), so let's close it. |
I noticed on my 32gb ram gaming desktop that my PC fan was always top speed. Checked and it's entirely vs code. Expanded and it's rust-analyzer.exe at very high power usage and using nearly all CPU and RAM. I've got a basic tauri app and I'm not sure what it's doing in the background but it really goes brrr |
I have this problem with any project with a big number of dependencies (and subdependencies). For example, any game, that uses Bevy game engine, OOM's VS Code quite often |
This is hopefully an actionable issue to mitigate this |
This comment has been minimized.
This comment has been minimized.
Of course it's loading |
This comment has been minimized.
This comment has been minimized.
We already do all of that. We use about 1.2 GB on rust-analyzer itself, which is a rather large codebase and seems pretty reasonable to me. Things might improve in the future, so please follow along. |
Ok thanks for your time (and the team as a whole, for their work!) I'll hide my comment as outdated |
It seem to me that RA basically builds the project and maintains a collection of build files in live memory, at least that is how I explain its high memory usage.
After opening a rust project with vs code and RA extension the rust-analyzer process takes 1GB RAM upwards and CPU is constantly at around 20%, which seems like a lot if it isn't doing anything. It makes it unpleasant to have the editor running in the background for example.
Are there any reasons for this? Can this be fixed? I feel like this has been a major issue with RA for a long time and it hasn't really been improving despite a lot of updates.
I wonder why RA can't just look for existing source files and dependencies etc, check if they are up to date, if not lock the build directory and update, then use the on-disk build artifacts it needs, does any indexing etc. to show types and auto completion, caches that on disk to reuse for next session, updates the index if files change and then only calls cargo check to get errors and warnings, updates the index only when files change, etc. I don't know where 1GB of RAM would be needed here while idling, let alone using that much CPU. The index doesn't seem like it should be that large.
Sorry, I don't mean to sound off putting, and I know this is open source software, but I feel like these issues are not getting enough attention or explanation as to why they can't be fixed. If it is a developer resources issue it would certainly help if we can document where performance issues might stem from.
The text was updated successfully, but these errors were encountered: