Have you ever wondered exactly how all the physical memory in a Firefox OS device is used? Wonder no more. I just landed a system-wide memory reporter which works on any Firefox product running on a Linux system. This includes desktop Firefox builds on Linux, Firefox for Android, and Firefox OS.

This memory reporter is a bit different to the existing ones, which work entirely within Mozilla processes. The new reporter provides measurements for the entire system, including every user-space process (Mozilla or non-Mozilla) that is running. It’s aimed primarily at profiling Firefox OS devices, because we have full control over the code running on those devices, and so it’s there that a system-wide view is most useful.

Here is some example output from a GeeksPhone Keon.

System Other Measurements 397.24 MB (100.0%) -- mem ├──215.41 MB (54.23%) ── free ├──105.72 MB (26.61%) -- processes │ ├───57.59 MB (14.50%) -- process(/system/b2g/b2g, pid=709) │ │ ├──42.29 MB (10.65%) -- anonymous │ │ │ ├──42.25 MB (10.63%) -- outside-brk │ │ │ │ ├──41.94 MB (10.56%) ── [rw-p] [69] │ │ │ │ └───0.31 MB (00.08%) ++ (2 tiny) │ │ │ └───0.05 MB (00.01%) ── brk-heap/[rw-p] │ │ ├──13.03 MB (03.28%) -- shared-libraries │ │ │ ├───8.39 MB (02.11%) -- libxul.so │ │ │ │ ├──6.05 MB (01.52%) ── [r-xp] │ │ │ │ └──2.34 MB (00.59%) ── [rw-p] │ │ │ └───4.64 MB (01.17%) ++ (69 tiny) │ │ └───2.27 MB (00.57%) ++ (2 tiny) │ ├───21.73 MB (05.47%) -- process(/system/b2g/plugin-container, pid=756) │ │ ├──12.49 MB (03.14%) -- anonymous │ │ │ ├──12.48 MB (03.14%) -- outside-brk │ │ │ │ ├──12.41 MB (03.12%) ── [rw-p] [30] │ │ │ │ └───0.07 MB (00.02%) ++ (2 tiny) │ │ │ └───0.02 MB (00.00%) ── brk-heap/[rw-p] │ │ ├───8.88 MB (02.23%) -- shared-libraries │ │ │ ├──7.33 MB (01.85%) -- libxul.so │ │ │ │ ├──4.99 MB (01.26%) ── [r-xp] │ │ │ │ └──2.34 MB (00.59%) ── [rw-p] │ │ │ └──1.54 MB (00.39%) ++ (50 tiny) │ │ └───0.36 MB (00.09%) ++ (2 tiny) │ ├───14.08 MB (03.54%) -- process(/system/b2g/plugin-container, pid=836) │ │ ├───7.53 MB (01.89%) -- shared-libraries │ │ │ ├──6.02 MB (01.52%) ++ libxul.so │ │ │ └──1.51 MB (00.38%) ++ (47 tiny) │ │ ├───6.24 MB (01.57%) -- anonymous │ │ │ ├──6.23 MB (01.57%) -- outside-brk │ │ │ │ ├──6.23 MB (01.57%) ── [rw-p] [22] │ │ │ │ └──0.00 MB (00.00%) ── [r--p] │ │ │ └──0.01 MB (00.00%) ── brk-heap/[rw-p] │ │ └───0.31 MB (00.08%) ++ (2 tiny) │ └───12.32 MB (03.10%) ++ (23 tiny) └───76.11 MB (19.16%) ── other

The data is obtained entirely from the operating system, specifically from /proc/meminfo and the /proc/<pid>/smaps files, which are files provided by the Linux kernel specifically for measuring memory consumption.

I wish that the mem entry at the top was the amount of physical memory available. Unfortunately there is no way to get that on a Linux system, and so it’s instead the MemTotal value from /proc/meminfo , which is “Total usable RAM (i.e. physical RAM minus a few reserved bits and the kernel binary code)”. And if you’re wondering about the exact meaning of the other entries, as usual if you hover the cursor over an entry in about:memory you’ll get a tool-tip explaining what it means.

The measurements given for each process are the PSS (proportional set size) measurements. These attribute any shared memory equally among all processes that share it, and so PSS is the only measurement that can be sensibly summed across processes (unlike “Size” or “RSS”, for example).

For each process there is a wealth of detail about static code and data. (The above example only shows a tiny fraction of it, because a number of the sub-trees are collapsed. If you were viewing it in about:memory, you could expand and collapse sub-trees to your heart’s content.) Unfortunately, there is little information about anonymous mappings, which constitute much of the non-static memory consumption. I have some patches that will add an extra level of detail there, distinguishing major regions such as the jemalloc heap, the JS GC heap, and JS JIT code. For more detail than that, the existing per-process memory reports in about:memory can be consulted. Unfortunately the new system-wide reporter cannot be sensibly combined with the existing per-process memory reporters because the latter are unaware of implicit sharing between processes. (And note that the amount of implicit sharing is increased significantly by the new Nuwa process.)

Because this works with our existing memory reporting infrastructure, anyone already using the get_about_memory.py script with Firefox OS will automatically get these reports along with all the usual ones once they update their source code, and the system-wide reports can be loaded and viewed in about:memory as usual. On Firefox and Firefox for Android, you’ll need to set the memory.system_memory_reporter flag in about:config to enable it.