about:memory and the memory reporter infrastructure that powers it are amazing. They provide an explicit hierarchy that breaks down the memory use in the system to the subsystems and increasingly the causes of allocation. about:memory looks like this (if you stand a few feet back from your monitor and take off your glasses):
If you are going to look at about:memory, it is probably for one of two reasons:
- You are Nicholas Nethercote or one of his merry band of MemShrink hackers kicking ass and taking names (of inefficient uses of memory). In this case, about:memory is exactly what you need.
- You suspect some tab in Firefox has gone crazy and you want to figure out which one it is and take your vengeance upon it. Vengeance can take the form of thinking mean thoughts, closing the tab, or writing a snarky tweet. about:memory will let you do this, but you have to look at a lot of text and you may already be too late to find the culprit! If only there was an easier way…
Enter about:nosy:
It can show us a list of all the open tabs and their memory usage sans JS for now, as per the above screenshot. If you expand the tab capsules, you get to see the list of all the inner windows/iframes that live in the hierarchy of that page. In most cases the list is either really short and boring or really long and boring. In the case of www.cnn.com I end up with 26 inner windows.
It can also show us memory aggregated by origin. We do show JS for this case because JS is currently only trackable on a per-origin basis. When Bug 650353 gets fixed or the memory reporters get more specific we should be able to apportion JS usage to pages directly.
It also attempts to aggregate extension JS compartments back to their owning extension. We ask the add-on manager for a list of the installed extensions to find their filesystem roots, ask the resource protocol to explain resource mappings, and from there are able to translate such paths. Just keep in mind that traditional overlay-based extensions do not create their own compartments and so are invisible for tracking purposes.
In the screenshot above, you can see that about:nosy keeps the charts exciting by generating a ridiculous amount of garbage all by itself. Much of this is just the about:memory tree-building code that we are reusing. If you refreshed about:memory once a second you would probably see similar garbage creation from the main system JS compartment.
You can install a restartless XPI (update: points at 0.3 now which does not screw up style shell apportionment and uses a better add-on SDK that does not create throwaway JS compartments every second) of the state of the now that will not auto-update. It wants a recent nightly build of Firefox because it makes assumptions about the structure of the memory reporters in order to better serve you.
You can find the source repo on github. It requires the add-on SDK to build. It might seem a little overkill for just graphing memory history, but if you’re looking at the repo you will notice my goal is to use Brian Burg‘s jsprobes work aided by Steve Fink and now de-bitrotted by me (but still a bit crashy) to be able to graph CPU usage, including raw JS, layout/reflow, and paint (eventually, after adding probe points). It’s also possible for those statistics to be gathered via static mechanisms, but the probes are fun and I want to see them work.
Superhero work. NN will no doubt rave about this in next week’s MemShrink update.
Hopefully something similar will come to the Snappy project very soon!
This looks fantastic! Nice work!
GREAT work! BIG thank you!
Cool!
I appreciate that this tool emphasizes relative memory usage rather than absolute numbers. The numbers aren’t particularly meaningful at this point, but the relative usage should be correct enough to be useful!
Nice, though as some users point out, it may make firefox lag sometime, maybe it’s better to put a setting interval about the speed it refresh.
Not working with SeaMonkey Nightly even after adding appropriate section in install.rdf, just getting “The URL is not valid and cannot be loaded” when entering about:nosy, can you fix this please?
Thanks for the positive feedback everyone!
Dindog, internally, the interval is configurable, so it should be fairly easy to expose that, especially now that I believe the add-on SDK has an easy-to-use preferences mechanism that automatically surfaces a UI.
Px, I fear that the problem may be with the Add-on SDK not liking SeaMonkey rather than my extension. Specifically, I know it likes to check the application id in many cases and throw if it thinks it doesn’t support the app. That’s my best guess as to what is happening.
The attempt to blame memory usage on extensions is awesome.
Hmm… how hard would it be to highlight suspected zombie compartments? (And with it, “This compartment has been alive for 326 seconds since the last tab/docshell/whatever containing it was closed”?) And render them with a rotting flesh background texture?
Hmm… I wonder if there’s a way for the slower memory reporters only sample a subset of their items. It’d be nice to slow down and stagger the sampling for inactive tabs.
Detecting zombie compartments should not be too hard. We could even maintain a count of the number of GCs that have passed and say “and it survived N GC’s”. Is that a common problem?
It would indeed be great if we had more knobs for the memory reporters and could be more memory efficient. I’m not sure it’s worth the complexity at this point, but I think it would be good to keep in mind for the next time the infrastructure needs to be rejiggered so that it can also support abuses of it such as this one 🙂
Nice! But I bet https://bugzilla.mozilla.org/show_bug.cgi?id=713799 and https://bugzilla.mozilla.org/show_bug.cgi?id=687724 are going to break this 🙁
Once those bugs are fixed, my hope is that someone with better UX skills than me will write a easy-to-understand, high-level UI for seeing the per-tab memory usage, much like what you’ve done.
aboutMemory.js has been changing a lot lately, and will continue to do so. I’ve done some stuff to make it allocate less memory, see https://bugzilla.mozilla.org/show_bug.cgi?id=722969 and https://bugzilla.mozilla.org/show_bug.cgi?id=722972. Even after the latter bug is fixed it’ll still be way too inefficient for running once per second!
Ping me on IRC (“njn” on #memshrink) if you want to talk more!
I’m very happy about the upcoming bugs to have most of the per-tab information already served up on a platter! I will happily update the extension, especially as it should mainly be deleting code :).
Andrew, I search through files inside package and see that SeaMonkey are declared in functions among other Mozilla projects, and because addon url doesn’t working at all and not throw any error, I suppose there is something wrong in url register/calling code. Also, I must mention that similar experimental about:jank addon (https://github.com/jrmuizel/about-jank) works in same conditions just fine