LWN.net Logo

Blizzard: Goals for multi-process Firefox

Christopher Blizzard describes the goals for - and motivations behind - the move toward multi-process Firefox. "Physical pages of memory are allocated at the operating system layer and handed to user processes, at the process level, as virtual pages. The best way to return those to the operating system is to exit the process. It's a pretty high-level granularity for recycling memory, for very long-running browser sessions it's the only way to get predictable memory behaviour. This is why content processes offer a better model for returning memory to the operating system over time."
(Log in to post comments)

Blizzard: Goals for multi-process Firefox

Posted Jul 22, 2011 13:51 UTC (Fri) by xophos (subscriber, #75267) [Link]

To me that sounds a little like: we can't get garbage collection right so by giving each window/tab its own process we can at least make sure its resources are freed when it's closed.
I hope that's not really what is meant.

Blizzard: Goals for multi-process Firefox

Posted Jul 25, 2011 11:35 UTC (Mon) by nye (guest, #51576) [Link]

>To me that sounds a little like: we can't get garbage collection right so by giving each window/tab its own process we can at least make sure its resources are freed when it's closed.
>I hope that's not really what is meant.

The quoted section is talking about memory *fragmentation*, which is a considerably more difficult problem to solve for large long-running processes.

Blizzard: Goals for multi-process Firefox

Posted Jul 26, 2011 11:33 UTC (Tue) by njwhite (subscriber, #51848) [Link]

In the "Predictable memory behaviour" section of the article they mention this:

"Over the long term, heap allocation will grow and cause memory to “leak.” This isn’t a problem that’s specific to Firefox. Just about every long-running process with even mildly complex allocation patterns suffers from this problem."

Which is indeed not a particularly inspiring reason to switch to the multi-process model. The other goals are, though.

Blizzard: Goals for multi-process Firefox

Posted Jul 26, 2011 12:03 UTC (Tue) by nye (guest, #51576) [Link]

>Over the long term, heap allocation will grow and cause memory to “leak.”

The scare quotes here are important. They aren't talking about memory leaks, but memory 'leaks'. That is, memory which is correctly accounted and freed by the application, but nevertheless essentially lost due to heap fragmentation.

The effect is the same as if the memory were actually leaked, since that section of the heap is unlikely to be available to satisfy demands for heap allocations, but the application has actually released it so can't do much about it without being massively redesigned to alter its memory allocation patterns in an attempt to stop fragmentation from happening in the first place.

Blizzard: Goals for multi-process Firefox

Posted Jul 26, 2011 12:22 UTC (Tue) by njwhite (subscriber, #51848) [Link]

> The scare quotes here are important. They aren't talking about memory leaks,
> but memory 'leaks'. That is, memory which is correctly accounted and freed
> by the application, but nevertheless essentially lost due to heap
> fragmentation.

Ah, I see, thanks for explaining. I hadn't really thought about heap fragmentation before, and didn't read the article as closely as I should have.

Blizzard: Goals for multi-process Firefox

Posted Jul 26, 2011 17:37 UTC (Tue) by njs (guest, #40338) [Link]

The other option would be to implement some kind of compacting collector. If they can precisely identify all pointers (at least in some largish part of the heap, like, say, all the javascript?) then this should be possible in principle. Whether it's actually worth the nasty engineering involved is another question...

Blizzard: Goals for multi-process Firefox

Posted Jul 30, 2011 5:37 UTC (Sat) by elanthis (guest, #6227) [Link]

And assuming that the compacting collector doesn't have performance problems, like every single GC in the world actually has no matter how much their proponents want to claim otherwise. (I myself am an ex-proponent of GC.)

The best of the best of the GCs around are still unusable in applications like games because the latency they impose is noticeable to users. And as Web browsers become increasingly used as general application development platforms -- including game development platforms -- that latency becomes a problem. JS imposes it already in the limited context of the core logic. Imposing it for _everything_ could potentially be a big problem.

Blizzard: Goals for multi-process Firefox

Posted Jul 30, 2011 15:51 UTC (Sat) by njs (guest, #40338) [Link]

Well, they're going to be using GC anyway -- the whole Firefox UI is written in Javascript, not just scripts inside webpages. And fragmentation causes its own performance problems. So who knows how it works out on net. But the multi-process solution is so much simpler that probably none of this matters anyway.

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 12:56 UTC (Mon) by nix (subscriber, #2304) [Link]

The best of the best of the GCs around are still unusable in applications like games
This explains why so many very, very, very large games are scripted using Lua, which is not only garbage-collected but GCed using a very simple stop-the-world incremental collector which comes in at only a few hundred lines long?

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 15:20 UTC (Mon) by nye (guest, #51576) [Link]

>This explains why so many very, very, very large games are scripted using Lua

"scripted using" != "written in"

Try not to focus on picking apart a specific literal interpretation of the statement when the meaning is pretty clear.

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 16:26 UTC (Mon) by nix (subscriber, #2304) [Link]

The fact remains that long GC pauses inside Lua while a game object is waiting for a script response could still be destructive to interactive performance. But, oddly, this doesn't happen -- because even that simple GC is bloody fast (who cares about 1/10s delay here and there?)

In practice, GC is problematic when hard realtime response is required, when really fast (millisecond-scale) response is required, or when the GC is really bad so that huge delays are possible (e.g. Emacs's GC). In other situations -- which are *very* common -- you can use GC without worry.

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 16:47 UTC (Mon) by nye (guest, #51576) [Link]

>The fact remains that long GC pauses inside Lua while a game object is waiting for a script response could still be destructive to interactive performance. But, oddly, this doesn't happen --

It does indeed happen. Let's take as an example the game which introduced more people to Lua than any other application: WoW.

A great difficulty in writing non-trivial WoW addons is understanding how the GC works and optimising your code with that knowledge. Addon authors who assume things like creating a small throwaway table will be cheap end up causing the UI to pause noticeably when those tables eventually get GCd. Memory management actually ends up being a big deal because if you're not careful with how you use it you can cause major performance degradation.

>because even that simple GC is bloody fast (who cares about 1/10s delay here and there?)

A number of demographics, including audio/video editors and - crucially - gamers. 100ms is a *really long time*.

The reason Lua is the de facto choice for game scripting languages is that all other scripting languages are worse; that doesn't mean it's perfect.

Blizzard: Goals for multi-process Firefox

Posted Aug 3, 2011 4:52 UTC (Wed) by elanthis (guest, #6227) [Link]

Yes, Lua is mildly popular in games (not nearly as much as the Interwebz seems to think, but that's the Internet for you).

> The fact remains that long GC pauses inside Lua while a game object is waiting for a script response

If you were careless enough to write your game logic so that a GC invocation could possibly be triggered while a "game object waits for a script response", sure. And this happens in some games. And it pisses players off when it does.

> who cares about 1/10s delay here and there?

Are you fscking kidding me? We care a massive amount about that! You have a ~16ms budget for any given frame if we want to maintain a smooth 60 FPS. And yes, an occasional glitch for even a single frame that pulls us down to 10 FPS (or even 40 FPS) like you indicate is incredibly noticeable and disruptive. Given how much of that 16ms budget is going to be taken up by useful work by the actual game logic (30% is not uncommon), physics (40% is not uncommon), graphics ("way too damn much"% is not uncommon), etc., we've got a fraction of a millisecond to waste on something like unnecessary memory book-keeping -- at the absolute most -- and that's only assuming the game isn't already pushing the hardware to its limits. If we're on a console or other "out-dated" hardware where many triple-A games have to pull ridiculous tricks just to maintain a smooth 30 FPS, we have absolutely no time to waste at any moment. Spikes in the frame time are significantly worse than anything else; it's way better to the play experience to run at a smooth 30 than it is to run an almost-but-not-quite smooth 60, and some crazy algorithm that might want to semi-randomly scan a large chunk of your memory for garbage is just bad juju.

When something like Lua is used, you'd be surprised at the hoops that are jumped through. It's not uncommon to see Lua states created for every invoked script backed by a custom push/pop scratch memory allocator with the GC flat out disabled so that there is O(1) memory collection time after the script completes. Alternatively, the working set is kept so small via the aforementioned why-even-use-Lua-if-you-do-these tricks that the GC basically has next to no work to do and can be invoked at the end of every frame while waiting for the framebuffer swap. Or the working set's growth is painfully minimized so that the GC only normally needs to be run during level transitions. Or some other trick that is basically comprised of not taking any real advantage of the language to ensure that the GC doesn't screw you.

The same applies to most other off-the-shelf scripting languages used in games, including Scheme (e.g. Naughty Dog), C# (e.g. Unity, and a much much smaller percentage of successful XBLA games than Microsoft wants the general public to believe), Java (e.g. Looking Glass, and Tabula Rasa iirc), Flash (a surprisingly large number of AAA games, actually, via the ScaleForm UI library), Python (e.g. Disney in a few Z-budget games), etc. I'm actually having trouble thinking of any recent major games that I know for sure use Lua, but I'd be surprised if there aren't a few.

Every single one of the major commercial engines implement their own scripting language. Languages that are explicitly designed either to not need GC at all or to only need it in ways that are trivial to handle in bounded time (like reference counting based schemes, where deallocation penalties are paid at the exact moment that an object is unref'd, which makes finding, identifying, and fixing problematic scripts trivial via an engine-integrated script debugger/profiler).

Now, of course there are games that don't follow these rules, and blindly use something like Lua exactly the way you suggest is kosher. You have probably seen these games mentioned in reviews with comments like "choppy framerates" or "wth it runs like crap even on my $5,000 gaming rig" or "best student-project game ever!" :)

(Not to rag on student games. Some of them can be damn impressive. Far more impressive than any FOSS game I've ever seen, for that matter.)

> In practice, GC is problematic when hard realtime response is required

Maybe like applications that have to handle rich multimedia processing on top of a heavy physics simulation and advanced computer graphics that needs to maintain a consistent and unbroken stream of audio/video frames within a small fixed time slice all on relatively cheap, commodity consumer hardware... almost like video games. ;)

Blizzard: Goals for multi-process Firefox

Posted Aug 3, 2011 9:55 UTC (Wed) by nye (guest, #51576) [Link]

>I'm actually having trouble thinking of any recent major games that I know for sure use Lua, but I'd be surprised if there aren't a few.

Going even further offtopic: Civ V uses it for quite a lot - and it does indeed have weird performance problems even on modern supercomputer-level hardware (of course, the two could be entirely unrelated).

Blizzard: Goals for multi-process Firefox

Posted Aug 3, 2011 10:22 UTC (Wed) by nix (subscriber, #2304) [Link]

Yeah, that kind of game (turn-based) probably has much less harsh realtime bounds :) though Civ V is bad, it can't be worse than the performance of Civ III, though I think that was a psychological illusion caused by its hideously clunky widget set. There's nothing like requiring multiple clicks on virtually everything before it will respond to make a smooth game seem like it's really really slow...

Blizzard: Goals for multi-process Firefox

Posted Aug 3, 2011 10:21 UTC (Wed) by nix (subscriber, #2304) [Link]

Thanks, fascinating stuff, this is worth this week's subscription easily :) it's harder realtime than I thought.

(I'm not sure why you don't GC in another thread while doing the non-Lua work in this one... hm, yes I am, you can't be certain that it'll complete in time and in any case it would cause cacheline bouncing. Blast.)

Blizzard: Goals for multi-process Firefox

Posted Aug 4, 2011 9:04 UTC (Thu) by elanthis (guest, #6227) [Link]

Yeah, the cache behavior is specially problematic on at least the 360. I'm not familiar with the specifics (not being a 360 developer myself), but I've been told that Microsoft shaved a few dollars per chip off by not including cache prefetching, so random access to memory is especially painful on the 360 compared to the PC.

On a side note, I can now definitively name a recent professional game that uses Lua: Insanely Twisted Shadow Planet by Fuel Cell for the 360, which launched today. It's an awesome little indie game and one of my friends worked on a good portion of the art for it, so please check it out. :)

Blizzard: Goals for multi-process Firefox

Posted Aug 4, 2011 18:46 UTC (Thu) by nix (subscriber, #2304) [Link]

No prefetching?! And this is a *game* machine? I suppose blits and the like are done in hardware these days so prefetching is less useful for that sort of big data block, but still, sheesh.

I'd try out the game you suggested if I had a game console, but I don't, and they don't seem to make simulators ;}

Blizzard: Goals for multi-process Firefox

Posted Aug 5, 2011 3:16 UTC (Fri) by elanthis (guest, #6227) [Link]

My apologies, it's not prefetching it's missing. It's something I was told by a Microsoft Games dev some months back, but as I don't currently do any Xbox work I didn't get into the specifics or make much effort to commit it properly to memory. :) All I can remember for sure is that it has some kind of performance issue with certain common load/store patterns, and that it was something Microsoft could have "fixed" by spending a few extra bucks per unit. You should probably talk to an experienced 360 dev to get the details. Sorry for the bit of misinformation there.

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 16:29 UTC (Mon) by nix (subscriber, #2304) [Link]

Further, the meaning of elanthis's statement that GCs were unusable in applications like games is surely that GCs are unusable in applications like games. Pointing out that GCs are in fact used so much in games that they are almost pervasive counts as a disproof in my eyes.

Sure, the *entire game* is not generally written in a GCed language: not every single object the game creates is part of a GCed arena. That doesn't change the act that elanthis's statement is simply wrong, no matter how nonliteral you want to be. It's simply that they are used where appropriate: i.e. not where millisecond-scale responses are required.

Blizzard: Goals for multi-process Firefox

Posted Aug 1, 2011 16:52 UTC (Mon) by nye (guest, #51576) [Link]

I still think you are nitpicking to the point of absurdity, given that the topic of the sentence you're objecting to is whether or not garbage collection is suitable for a 'game development platform'.

Would you be happier if he had said 'unusable *for* applications like games'?

Blizzard: Goals for multi-process Firefox

Posted Jul 30, 2011 16:45 UTC (Sat) by oak (guest, #2786) [Link]

While some part of the heap goes to managed JavaScript objects and there are some www-pages where such are responsible for most of the memory usage of that page, on some other www-pages most of the memory goes to Flashplayer plugin, but I think most commonly the memory goes to images and other similar resources used by JS etc code.

But even when you use your own heap for JS, use compacting garbage collector for that and run plugins like Flashplayer in separate processes, you still have the fragmentation issue for rest of the allocations.

Only way to get rid of the fragmentation in C & C++ is doing temporary allocations only after persistent allocations or allocations with longer life-time have been done, but www-browsers don't control the pattern of their allocations.

The code that browser loads from the network (HTML, JS, CSS, WebGL etc) and runs on your PC/phone, controls the life-time of those allocs and if you have multiple pages open at the same time, there's definitely longer term allocs being done after temporary ones. Besides, there's also www-page resource in-memory caching and references between pages, so the life-time of an object/resource doesn't necessarily even end when you close a page.

Glibc allocates smaller allocations from the heap and larger ones using mmap(). You can control this threshold with the _MALLOC_MMAP_THRESHOLD. Heap downside is that it fragments (memory can be returned to the *system* only from one end of heap), mmap() downside is that it's slow. I'm not sure whether jemalloc used in Firefox nowadays has similar knobs one could try.

Blizzard: Goals for multi-process Firefox

Posted Jul 28, 2011 12:00 UTC (Thu) by renox (subscriber, #23785) [Link]

Maybe you should read the whole thing not just the beginning: better resource handling, sandboxing, etc are also reasons why it's better to have process instead of thread.

If memory serves, Chromes gives you the option to *choose* between process and threads (with a command line option): that's the correct way to do it: processes for security, better management of resources and threads for computers with a really small amount of memory (though heap fragmentation may be a problem also depending on the GC).

Blizzard: Goals for multi-process Firefox

Posted Jul 30, 2011 15:28 UTC (Sat) by oak (guest, #2786) [Link]

If one uses processes instead of threads you may even get some percents speed up as code doesn't need to do locking (for each alloc etc).

Copyright © 2011, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds