Wow. I've got Apple Music/iTunes running for a week or so on this Catalina macOS and the process viewer reports 300MB (including sub-processes). I assume it's a native application. How does Spotify manage to use so much RAM??
The Spotify desktop client is architected such that each pane in the main window is essentially its own separate webapp, complete with duplicate (and triplicate, quadruplicate, etc) dependencies. They did this so their various teams don’t have to talk to each other.
Desktop Spotify has been a resource hungry mess for years now. It used to be known for prematurely wearing out SSDs by constantly writing stuff (cache I think?) to disk.
They also have this problem where a "Spotify Helper" can crash constantly, and you won't notice it unless you look at the process tree.
On macOS, this will start a ReportCrash process, and end up taking up an entire CPU core just repeatedly crashing, reporting a crash, restarting, etc. It also significantly impacts battery life.
This happens every day for me. It's arguably worse than the SSD-killing SQLite vacuum problem they had.
> They did this so their various teams don’t have to talk to each other.
This is absolutely dreadful. I've unfortunately worked in multiple organisations where teams deconstructed their web-based products into microservices for this very reason.
I have found it to be rather buggy. I sometimes can't get songs to play, and other times can't get them to pause :) I switched to using their web interface in Firefox which has been totally rock solid.
Keybase also uses in the range of 600MB-1GB, and 8 processes, most of which don't exit when you exit the application. I'm not sure what Discord uses because I only run it in the browser, but I'm sure it's in the same range as all of the above.
I've come up with a powershell snippet to fully quit keybase and reclaim ~1GB RAM:
>I'm not sure what Discord uses because I only run it in the browser
Me too, and you just made me realize, there already exists a system for running Electron apps in a shared instance of Chrome, and it's installed on almost everyone's computer! You just... open the web version, in Chrome :)
Mind you, there's (sometimes a little, sometimes a lot) more to Electron than a webview. Some apps are running quite a bit of un-sandboxed native code—sometimes even forking off other native processes†—to do what they do. Keybase is, IIRC, one of the apps that are quite large on the "native" side.
† I once designed a system that has Electron install an Erlang release to the client, register it as a service, and start it. The Erlang node runs a locally-bound web server; the Electron app then visits that web server. All the data-wrangling happens in Erlang land, with Electron just serving as an HTML renderer for the pages coming from the local server. And yet Electron's native side is essential, here, because it ultimately manages the Erlang release (installing it, updating it, etc.) Erlang doesn't have any good tooling for doing client-native stuff on its own; Erlang devs find the whole idea of deploying an Erlang release to a client machine funny.
That's fantastic. I wonder if an elixir Phoenix / liveview use case with such a setup is reasonable now that elixir has releases. I think client native nifs are also not out of the question with the better tooling that comes out of modern langs like rust, nim, and my favorite zig.
The irony about that, is that not all electron apps are available from an URL. (now I know there is more than a webpage in a electron app, but with modern browsers you can have the same experience in a electron app or from a webapp pretty easily)
Over here, the base overhead of an Electron window is around 60MB. How do you know it's not those applications allocating a lot of memory that is causing all this usage?
Of course I don’t know that since I don’t have the time or ability to inspect what the apps are doing. :-) The best I can do is give comparisons to the old non-Electron versions of Spotify and Skype, which had all the same core features as the Electron versions and used less memory for the whole app than you’re saying a base Electron window costs.
It is difficult for me to lay blame at the feet of application developers (assuming they didn’t make the choice to use Electron) when the platform itself is so bad at giving developers ways to manage their apps’ memory usage.
If you want to listen for an event on a global object like `window`, the platform could give a way to do this using a weak reference, but it doesn’t, so you have to make sure to always remember to manually remove the listener yourself or else you’ve just leaked a bunch of stuff.
If you want to load an image, or some other media, the platform could give a way to control the runtime’s internal caches so you aren’t retaining data in memory that you don’t need—but it doesn’t, so you have to hope that the generic runtime memory cache from Chromium is intelligent enough not to retain unimportant things (and, in my experience, it’s not).
This problem has existed in one form or another in every Electron app I’ve ever used. Some are certainly worse than others, but I don’t think I’ve ever seen one come within even an order of magnitude of the memory usage of similar apps written natively.
It shows that the framework itself only uses 60MB and implies any higher usage is due to the application built on top of electron. I'm not sure why uptime matters unless you're assuming there are memory leaks?
The context here is that "the framework" does things 'for' the application it is hosting that the application cannot control, caching various things in memory in a way that makes sense for a browser, but not very much sense for a custom application.
Try this: open a new Chrome instance; look at its memory usage; then load a bunch of tabs (try an Open All on a bookmarks folder), close them all again, and then look at Chrome's memory usage again. It will have increased.
Chrome isn't leaking memory; instead, it is doing the same thing that an Operating System does: weakly reserving memory to optimistically cache stuff, releasing it again if there's enough memory pressure.
This works okay if you only have Chrome itself running. (Even then, its cache fights a bit with the OS page cache. It's certainly no Postgres, intentionally getting the OS page-cache to do its caching for it.) But as soon as you have two separate Chromium instances running (e.g. Chrome itself, plus an Electron app), then each one is going to try to "optimistically" cache as much stuff as it can, until it runs into the memory pressure created by the other instance caching as much stuff as it can, and so each instance will unload just a bit to let the other one cache just a bit more—back and forth—forever. Together, they thrash memory, and it becomes much harder for them to actually accomplish the "weak" part of "weak reservation", instead ending up hoarding all the memory between them.
This is the pretty much the same problem you see if you try to e.g. run two memory-heavy JVM processes (e.g. ElasticSearch) on the same system. Chrome is just one of the few times you'll see this "recapitulation of memory management within the runtime" effect client-side, rather than server-side.
What derefr said about Chrome holding on to memory, and additionally memory leaks are absolutely a concern for related reasons.
(Regarding uptime, it's not at all uncommon for Chrome's memory usage to double or even triple overnight. Partially a function of the websites you have open, sure, but also partially a function of Chrome itself).
Spotify: 1083.7 MB. VS Code: 890.9 MB. Skype: 406 MB.
In the past, I’ve had projects open in VS Code which have caused that number to shoot up into the multi-gigabyte range.
Of course this is all anecdotal but I am pretty sure these numbers come from actual experiences that people are having with Electron apps.