-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Excessive memory usage building GTK Rust, a problem for entry level devices for newcomers (e.g. Raspberry Pi 3+) #78308
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
Comments
Since you have 4 cores but only 2 GB of RAM, try building with only 1 codegen unit. |
Putting that into
(device became unresponsive afterwards) Also, would there be any way cargo could do this automatically on low memory devices? I'm not 100% sure I applied it correctly, although given Nevertheless, if it has done something of use then it seems like it wasn't enough to save the day, sadly. |
Try passing |
Okay, so I did want to leave it run for a while since it didn't instantly fully go out of memory / drop SSH as last time. However, the result of ninja limiting to one job + So that leaves me with: 1. still really wondering if cargo really should default to something more conservative with codegen units by default on any device with <3GB free memory, 2. rustc in overall still seems to go way overboard with memory use compiling GTK for Rust in a way that really is a showstopper on a 2GB mem device which seems quite unfortunate. (Might be just about workable on a 3-4GB device, I don't know. I might get a chance to test that in late November, or December.) |
If it's not enabled already, have you tried enabling zram (memory compression through the swap system)? Or if your storage device is fast enough, swap? |
@the8472 I heard that it works on the 3GB phone variant which I should own soon, but likely only if pretty much all other software is terminated. This seems unreasonable for a compiler, and I feel like we're just talking around the issue that rustc just appears to use too much memory compared to pretty much all other compilers when compiling a comparable program (a basic GTK+ app). Swap isn't the greatest idea because on the phone you can either put it on eMMC (which kills the phone when it dies) or the SD card (which is more prone to dying early under too heavy writing compared to "proper" desktop storage). zram might work, but only goes so far. Also, it doesn't change the fact that rustc needs ~1.8GB-2GB memory to build a GTK+ app, how is that not at least concerning? |
I was merely trying to offer options that are available now. Memory footprint optimizations rarely are easy and may also involve tradeoffs such as writing more data to disk instead (which would be similar to swapping anyway), disabling some features that keep large amounts of data in memory or doing smaller units of work which may increase compilation times. Even optimizations that require no feature tradeoffs still require development time. Anyway, another thing you can try is lowering the level of debuginfo, currently you're building with |
Just to point it out, this may still be preferable to general system swap however, since then it is only used during rustc compilation rather than potentially all the time.
This definitely sounds like something I would be looking for. The problem also is the many tweaks that keep being suggested are hard to apply for someone not using Rust themselves (I am not, I just want to test the dev version of that program) in a program with a complicated build tool like ninja (which I also don't use regularly myself), and it would help a lot if rustc detected little memory available and then did some aggressive tweaks in favor of lower memory use and higher compilation time on its own. I'm not sure how doable that is, just pointing it out as IMHO the ideal outcome from my view. |
Note that swap aggressiveness can be configured so that it is only used when there is no other choice
That may be acceptable for performance settings such as number of compiler threads but choices such as disabling debug info might end up overriding developer intent, e.g. when the developer chose to make a debug build.
Then note that you're trying to do a slow debug build. You probably want to create a release build instead. |
Well I was trying to test out an experimental build to give the developer feedback on the ticket, where having debug symbols might actually be useful if it misbehaves.
This tends to work out poorly in practice however, especially when combined with tools like earlyoom (which is kind of mandatory nowadays given how bad the kernel oom killer is). The points where it's reasonably killed early and where it should start using swap can be pretty close then, and usually I actually prefer the kill since as written above general swap use is not such a good idea on eMMC. So I think swap can't be done "half heartedly", either you're using it constantly on such a low memory device or not much at all even when needed. The system after all cannot really guess when it's rustc that I would actually like to keep running, unlike most other processes that go wild that would better be stopped. What I was hoping with this ticket is that there would be some recognition that this problem might be a little out of hand (which fwiw I'm not saying isn't there), and then some thought about some mechanisms to curb it automatically instead of leaving the user kind of stranded with difficult tweaks. Some mechanism to manually swap things to disk in rustc definitely sounds like the way to go IMHO, with that being connected to some way of actual free memory detection on the actual system at hand. Or of course algorithmic tweaks that improve this generally, although I understand all the obvious ones might already be done here. Edit: just to support this further, look at the discussion here: gtk-rs/gtk#1074 at some point rustc users just seem to be at a loss at how to adjust and break up their project to work around this, which is why I think eventually at a certain scale it would help if rustc considered it its own responsibility to not assume it can all stay in memory without disk swapping, giving how naturally memory heavy Rust compilation appears to be. There just seems to be an eventual problem of scale with that approach which in the end excludes lower spec device users (even if they would be patient enough to otherwise endure an excessive wait time). |
You can still try lowering debug info from 2 to 1. |
I think there's definitely recognition that rustc is a memory hog, based on discussions in the rust-lang Zulip. Some contributors, including myself, have to reduce the number of jobs when building rustc or else risk death by thrashing. I've just started looking into ways to reduce memory consumption, and I'm already seeing that there are potential reductions that I'm hopeful are realizable. As for actively adapting to memory usage, I wonder if it would be appropriate for cargo to try to manage this in part by adjusting the number of rustc instances dynamically based on some heuristic. |
I would like to point out that this could more easily be worked around if cargo provided an option to force some or all crate dependencies to be linked dynamically rather than statically, ABI stability be damned. :^) Stability between releases should be good enough for such use-cases and this should prevent most of these OOM scenarios. It just takes less memory to dynamically link to .so libraries than it does to statically link everything into one big blob. |
I tried to build this Rust project, an on-screen keyboard directly on-device on a PinePhone:
(install of some dependencies will likely be required before it runs through, it tells you which as you go)
I expected to see this happen: it works
Instead, this happened: it runs out of memory once it builds GTK for Rust:
This device has 2GB in total in memory as you can see. Now before you point out that may not be the typical developer device, the Raspberry PI also commonly has around that range in memory and is a common entry level device for tinkerers and new want-to-be programmers that try out their first steps. Please also note that some people from less fortunate backgrounds may not be able to afford a pricier device. Also, mobile phones used on the run for quick tasks, which might involve rebuilding an app locally as I tried here, are increasingly becoming more common. For all programming languages other than Rust that I've ever tried, this is not an issue: compilation may take long, maybe hours even for larger projects, but at least for regular desktop level applications outside of giants like browsers, or entire compiler toolchains themselves, it usually works, even if only with lots of patience. For Rust however, this doesn't seem to be currently the case.
I reported the issue to GTK for Rust which is the component that makes rustc run out of memory when compiled, where it was pointed out this is likely something that needs to be addressed in the compiler: gtk-rs/gtk#1074
Since this seems like a potentially major accessibility barrier for newcomers and people stuck with less powerful devices to get into the Rust world, I suggest that this situation should be improved.
Please note I am not objecting to this memory usage in environments where it is available, if that speeds up compilation (for caching etc). However, it shouldn't be a required amount to be able to build any basic graphical GTK application at all.
Meta
rustc --version --verbose
:(this is the compiler directly on the 2GB device, a PinePhone.)
The text was updated successfully, but these errors were encountered: