Tuesday, February 11, 2014

The end of OS/2, the beginning of MIPS, and the question of ads (plus: take out the garbage and the trash)

29 has officially moved into Aurora, the first version of what (we assume) will become the Australis Firefox. There are several bugs still pending related to OS X, and once those are fixed on Aurora, then we will try porting and God help us. For now I am taking a break from JavaScript work to do other things, such as my memorial to the old floodgap.com server, the Apple Network Server 500 and 700.

For 24.3.0 we made an apparently minor change to the user agent string by moving the TenFourFox token into middle position to stop Chase banking services from complaining users weren't using a supported browser. That worked, and instead broke Yahoo! Mail. So no more user agent changes and this one will be backed out for 24.4.0. Users who are bitten by this can use any of the user agent changer add-ons for now. The TenFourFox token must appear because we use it for detection purposes internally, and also because, believe it or not, some sites actually check for us and serve appropriate non-plugin content. Eventually when we drop source parity there will be a user agent pane in Preferences like Classilla has, but I'd rather users used an existing add-on while we still mirror ESR24.

For some time an annoyance has been that TenFourFox gets slower with prolonged use. Prolonged use means days to weeks, of course, but for those of us who never have crashes, the browser may only be restarted when there is an update to install. The reason for this is garbage collection: as more tabs are loaded and more pages are in use -- and recall that tabs keep a certain amount of in-memory cache for fast backup and forward -- the browser must visit these objects and determine if they are still referenced by something, and keep or dispose of them appropriately. This isn't a memory leak; it's just more stuff hanging around so that it can be referenced at will. We just need to manage it better.

Prior to Firefox 16/TenFourFox 17, garbage collection was an all-or-nothing phenomenon. It would occur (with a noticeable stall) and then keep going. In 16/17, Mozilla changed garbage collection to be incremental: the browser would divide garbage collection into time slices (default, 10ms) and execute those. If you can be reasonably certain enough work can occur in that timeslice so that the browser stays ahead of the problem, then this is fine, and makes the browser appear to garbage collect instantaneously on a modern system. Well, we're not modern systems, and arguably the 10ms time slice wasn't doing any significant garbage collection even on the G5, meaning it all slowly stacked up and the browser just scheduled garbage collection slices, over and over, forever.

For 24, I increased this time slice to 30ms. That helped by getting more done per slice, but eventually garbage still builds up and the browser gets into that vicious cycle again. There are two ways around this: make the time slice redonkulous, like 100ms, or turn off incremental garbage collection altogether and go back to the old periodic stop-the-world GC that would at least enable the browser to catch up even if now and then it will seize. Right now I'm testing option 2, and that's not doing too bad so far; my worry with option 1 is that if that cycle of GC after GC crops up again, then the slices it schedules are really long, and the browser gets starved for time to service user requests.

If you want to try this, you can, but if you screw this up you will significantly impact browser performance. Don't do this if you're not prepared for the consequences. For option 1, increase the value of javascript.options.mem.gc_incremental_slice_ms. For option 2, turn javascript.options.mem.gc_incremental off. Option 2, of course, overrides anything you have for option 1. Restart the browser to start from a clean slate. The browser will appear faster, of course, when you do; the real test is how it performs after a few days. If you don't know what these settings are or where you find them, you should not do this! I might consider adding this to the next unstable build based on people's opinions, but this is too risky a change for 24.

For those of you who are more risk-averse, remember that TenFourFox by default restores your tabs when the browser restarts, so if you restart the browser, all the tabs get unloaded and there are many fewer objects for the garbage collector to check (but they load when you access them). So, you can get the speed back with a quick restart add-on, and there is such an add-on available that adds a "Restart" hot key (Option-Command-R, or go to File and Restart), which amusingly doesn't require you to restart the browser to install. If this works well for folks, we'll make it an official recommendation. You can get Restartless Restart from Mozilla Add-ons.

In other news, Mozilla has officially removed all OS/2 code from the Firefox tree, finally ending that platform's support even as Tier-3. There have been problems with OS/2 support as far back as Firefox 3.6 and OS/2 support never officially made the jump to ESR17 even though there is a porting effort that did release a few beta builds. This doesn't mean there won't be another OS/2 Firefox, but it does mean that, like us, they'll have to take and port forward a lot of the pre-existing code, and it will require significantly more work for them because OS/2 is so unlike anything else. We ourselves remain a Tier-3 platform, but even if Mozilla took all the PowerPC OS X code out we would simply add it back in (and say mean things about them in this blog and make empty threats towards their pets and families), so this is more of a sad footnote than an actual change in service level.

So that's sad, but the hopeful part is that there is someone working on a MIPS port of IonMonkey and, surprisingly, asm.js/OdinMonkey. This is for mobile devices running MIPS, of course, so it's little-endian MIPS, but it is already making significant progress and we might be able to pattern our PowerPC port of IonMonkey off it. (I remain unconvinced of the utility of asm.js on big-endian platforms, given that all the extant asm.js code is little-endian and particularly the voluminous crapola code generated by Emscripten. We could make it byte-swap, maybe, but that would require two somewhat separate code generators and be a fabulous pain in the ass to manage.) I intend to watch their progress closely.

Finally, today's web hissy fit is about the possibility Mozilla may allow sponsored content on the new tab page. Sponsored tiles would be marked. That's about all we know; we don't know if third-party builds like us can (or will be forced to) also take part, we don't know what information the browser would collect, and we don't know how configurable it is (like whether it will always take up a certain number of tiles, or gradually disappear as the browser accumulates history, or how you can change that). The move does make some financial sense; Mozilla is too dependent on Google for income, and it needs to diversify its revenue stream to stay afloat. Furthermore, as a practical matter I'm not going to dismiss the idea immediately out of hand, because maintaining Floodgap is expensive and TenFourFox consumes a lot of my time, and while I have assiduously refused actual donations I obviously do accept ad revenue from this blog. If we got a cut, users could turn it off, and the information it collected was not personally offensive or overly intrusive, I would consider it. If we don't get a cut, I find it to be insufficiently configurable, or I conclude it collects an unacceptable amount of personal data, we would disable it at the code level. The whole idea is very embryonic. Either way you'll hear about it here.


  1. I'm going to test javascript.options.mem.gc_incremental_slice_ms = 100 and try not to restart the browser for a week.

  2. Just a comment on ads in the browser. Wouldn't AdBlock Plus or AdBlock Edge or any of the other myriad ad blocking addons render this idea pointless?

    Or is Mozilla really that clueless to the bazillions of users out there that use the addons?

    1. ABP/ABE probably won't halt this without modification, if my guess about implementation turns out to be right. Of course, I'm sure they will be modified to do so post-haste.

  3. After a week of testing with javascript.options.mem.gc_incremental_slice_ms = 100 (PowerBook G3 1.33 HGz with 2 GB RAM):

    For general browsing I would be hard-pressed to describe a performance difference between the 30 and 100 ms settings. Memory usage goes up quickly when the browser has a lot to do. Maximum value was 997 MB for the test week. When the heavy load is over and tabs are closed it goes down again rather quickly (about 100 MB per minute), but it can't or won't to go all the way down to the ~230 MB it started with. Rather, the minimum value increases day by day and was at about 600 MB the last day of the test week. The more memory the browser uses, the slower it is overall.

    There's almost never real stalling (beachball) even when the browser has to load 40 Facebook tabs at the same time. In such a situation the browser stays responsive for user input, but it's slow, of course.

    The browser didn't crash even once (because: no plugins).

    Now one week with javascript.options.mem.gc_incremental = off.

    1. Thanks, that's really helpful to know. I'm using the 100ms approach now and it appears to be smoother than turning incremental off, at least on this G5. However, I'm pairing it with setting browser.sessionstore.max_tabs_undo to 2 so that the browser is more likely to reclaim memory from recently closed tabs but still keeps a couple around. I don't have enough testing to say if I like this or not, but I don't miss not having the other eight tabs to undo, so I think it's workable at least with my browsing habits. I'd like to hear what others think.

    2. I aborted the javascript.options.mem.gc_incremental = off experiment after three days. It produces more stalls. Here, as well, memory usage is never reduced by more than 400 MB, so once it's over 900 MB it will always stay in an unhealthy and slow region of 600 MB or higher. Maximum on Febr. 20 was 1120 MB, and after that it never went below 700 MB, even though I left it idle with no window open for half a day. I'll try lowering browser.sessionstore.max_tabs_undo as well, maybe this helps. If it doesn't, periodic restarts would be the only remedy, I guess.

    3. I don't see much of a difference with only two tabs in the sessionstore. It's odd that the browser can't take out all the garbage. What is it doing with hundreds of megabytes of unused objects in the memory?


Due to an increased frequency of spam, comments are now subject to moderation.