Quick background
With the e10s project full steam ahead, likely to be enabled for many users in mid-2016, it seemed like a good time to measure the memory overhead of switching Firefox from a single-process architecture to a multi-process architecture. The concern here is simple: the more processes we have, the more memory we use. Starting Q4-2015 I began setting up a test to measure the memory usage of Firefox with a variable amount of content processes.
Methodology
For the test I used a slightly modified version of the AWSY framework that I maintain for areweslimyet.com. This test runs through a sample pageset, the same one used in Talos perf testing, in an attempt to simulate a long-lived session.
The steps:
- Open Firefox configured to use N content processes.
- Measure memory usage.
- Open 100 urls in 30 tabs, cycling through tabs once 30 are opened. Wait 10 seconds per tab.
- Measure memory usage.
- Close all tabs.
- Measure memory usage.
For this test I performed two iterations of this, reporting the startup memory usage from the first and the end of test memory usage (TabsOpen, TabsClosed) for the second.
Note: Just summing the total memory usage of each Firefox process is not a useful metric as it will include memory shared between the main process and the content processes. For a more realistic baseline I chose to use a combination of RSS and USS (aka unique set size, private working bytes):
total_memory = RSS(parent_process) + sum(USS(content_processes))
For example if we had:
Process | RSS | USS |
---|---|---|
parent | 100 | 50 |
content_1 | 90 | 30 |
content_2 | 95 | 40 |
total_memory = 100 + 30 + 40
Results
Note on memory checkpoints:
Settled
: 30 seconds have passed since previous checkpoint.ForceGC
: We manually invoked garbage collection.- We list the memory usage for each checkpoint using 0, 1, 2, 4, 8 content processes.
Linux, 64-bit
0 | 1 | 2 | 4 | 8 | |
---|---|---|---|---|---|
Start | 190 MiB | 232 MiB | 223 MiB | 223 MiB | 229 MiB |
StartSettled | 173 MiB | 219 MiB | 216 MiB | 219 MiB | 213 MiB |
TabsOpen | 457 MiB | 544 MiB | 586 MiB | 714 MiB | 871 MiB |
TabsOpenSettled | 448 MiB | 542 MiB | 582 MiB | 696 MiB | 872 MiB |
TabsOpenForceGC | 415 MiB | 510 MiB | 560 MiB | 670 MiB | 820 MiB |
TabsClosed | 386 MiB | 507 MiB | 401 MiB | 381 MiB | 381 MiB |
TabsClosedSettled | 264 MiB | 359 MiB | 325 MiB | 308 MiB | 303 MiB |
TabsClosedForceGC | 242 MiB | 322 MiB | 304 MiB | 285 MiB | 281 MiB |
Windows 7, 64-bit
32-bit Firefox
0 | 1 | 2 | 4 | 8 | |
---|---|---|---|---|---|
Start | 172 MiB | 212 MiB | 207 MiB | 204 MiB | 213 MiB |
StartSettled | 194 MiB | 236 MiB | 234 MiB | 232 MiB | 234 MiB |
TabsOpen | 461 MiB | 537 MiB | 631 MiB | 800 MiB | 1,099 MiB |
TabsOpenSettled | 463 MiB | 535 MiB | 635 MiB | 808 MiB | 1,108 MiB |
TabsOpenForceGC | 447 MiB | 514 MiB | 593 MiB | 737 MiB | 990 MiB |
TabsClosed | 429 MiB | 512 MiB | 435 MiB | 333 MiB | 347 MiB |
TabsClosedSettled | 356 MiB | 427 MiB | 379 MiB | 302 MiB | 306 MiB |
TabsClosedForceGC | 342 MiB | 392 MiB | 360 MiB | 297 MiB | 295 MiB |
64-bit Firefox
0 | 1 | 2 | 4 | 8 | |
---|---|---|---|---|---|
Start | 245 MiB | 276 MiB | 275 MiB | 279 MiB | 295 MiB |
StartSettled | 236 MiB | 290 MiB | 287 MiB | 288 MiB | 289 MiB |
TabsOpen | 618 MiB | 699 MiB | 805 MiB | 1061 MiB | 1334 MiB |
TabsOpenSettled | 625 MiB | 690 MiB | 795 MiB | 1058 MiB | 1338 MiB |
TabsOpenForceGC | 600 MiB | 661 MiB | 740 MiB | 936 MiB | 1184 MiB |
TabsClosed | 568 MiB | 663 MiB | 543 MiB | 481 MiB | 435 MiB |
TabsClosedSettled | 451 MiB | 517 MiB | 454 MiB | 426 MiB | 377 MiB |
TabsClosedForceGC | 432 MiB | 480 MiB | 429 MiB | 412 MiB | 374 MiB |
OSX, 64-bit
0 | 1 | 2 | 4 | 8 | |
---|---|---|---|---|---|
Start | 319 MiB | 350 MiB | 342 MiB | 336 MiB | 336 MiB |
StartSettled | 311 MiB | 393 MiB | 383 MiB | 384 MiB | 382 MiB |
TabsOpen | 889 MiB | 1,038 MiB | 1,243 MiB | 1,397 MiB | 1,694 MiB |
TabsOpenSettled | 876 MiB | 977 MiB | 1,105 MiB | 1,252 MiB | 1,632 MiB |
TabsOpenForceGC | 795 MiB | 966 MiB | 1,096 MiB | 1,235 MiB | 1,540 MiB |
TabsClosed | 794 MiB | 996 MiB | 977 MiB | 889 MiB | 883 MiB |
TabsClosedSettled | 738 MiB | 925 MiB | 876 MiB | 823 MiB | 832 MiB |
TabsClosedForceGC | 621 MiB | 800 MiB | 799 MiB | 755 MiB | 747 MiB |
Conclusions
Simply put: the more content processes we use, the more memory we use. On the plus side it’s not a 1:1 factor, with 8 content processes we see roughly a doubling of memory usage on the TabsOpenSettled
measurment. It’s a bit worse on Windows, a bit better on OSX, but it’s not 8 times worse.
Overall we see a 10-20% increase in memory usage for the 1 content process case (which is what we plan on shipping initially). This seems like a fair tradeoff for potential security and performance benefits, but as we try to grow the number of content processes we’ll need to take another look at where that memory is being used.
For the next steps I’d like to take a look at how our memory usage compares to other browsers. Expect a follow up post on that shortly.
Any idea why OSX is so large compared to the others?
What is the bit width of each of these? Are they all 64-bit?
Why OSX is so high (like 2X high) is still a mystery to me (to a degree Chrome has the same problem). I tested:
Could the memory usage on OSX have something to do with the fact that the OS doesn’t release madvise(MADV_FREE)d pages unless it needs to? We have a function in mozjemalloc to “double purge” these, called by about:memory before measurements (not sure if GC pages have or work around the same problem).
These measurements were using the about:memory mechanism, so they should have double-purged.
OK, thanks for confirming that.
I added 64-bit Firefox as well.
Retina resolution maybe?
Any idea what 64bit-FF on Win64 looks like?
I imagine the difference is similar to 32, but we’d have to measure to find out. I can retest against a nightly now that the USS code has landed.
I updated the post with numbers for 64-bit on Windows. This was testing on a nightly from yesterday, so comparing with 32-bit measurements from a month ago is a bit dubious. We see percentage overhead is similar (possibly a bit better), but overall memory usage is worse compared to 32-bit. This is in line with measurements I’ve done previously where we see a roughly 25% increase in memory usage going from 32 -> 64 on Windows.
The problem is not how much RAM use Firefox with e10s enabled, but how much memory is released by e10s on tabs closing.
That’s an interesting metric, we actually do better in the 8 process case on Windows after all tabs are closed. That’s probably due to the fragmentation problems we’ve seen there. We fair worse on OSX and Linux though.
The down side is that’s really only useful if the user closes all of their tabs, which seems like a rare use case.
Looks like maybe one tab is being left open. eg about:home
We close all tabs but one, then navigate that to about:blank. Source is here
If the final steps were something like;
Open a new tab. (This currently does not open in the content process, (eventually will.))
Close others.
Pause a bit, not sure how long. (maybe gc/cc)
Then navigate to home. Then if wanted to blank. (blank is extra special as it stays same as whatever prior page was.)
A new content process would open.
With any luck 1,2,4,8 would end with the same memory usage.
These are bad news for me(and i guess for the average user too): i choose firefox over chrome/chromium because of its memory footprint. Browsers are applications that usually are always open and stay there until computer is powered off(if it does), plus in the last couple of years there wasn’t a big increase on the average RAM size to enable.
I’m using Mozilla for single process reason. what i need use now ? Edge ? maybe.
I don’t understand why Mozilla is copying worst Chrome browser on everything. FF is better in all areas now.
All major browsers, including Edge, are now multiprocess. You might find my next post detailing memory usage across multiprocess browsers interesting.
Stability – yes. Speed – doubtful.
I doubt this is a positive direction for FF.
It will increase ram memory usage by 20% and increase CPU usage too.
Not sure it is worth the change. Improve – not sure.
I m happy to trade more RAM for the speed and stability I find with e10s. I know loads of people seem to have issues with it though.
The point is that if you fill the RAM all your processes will get slower, browser included. Still average consumer-desktop has 4 GB of ram, and it runs on windows, which needs an antivirus. I would prefer smaller RAM consumption and faster browser, with less features natively, more freely extensible (where the new Firefox plugin system make extension less powerful).