Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

> Splitting UI from content means that when a web page is devouring your computer’s processor, your tabs and buttons and menus won’t lock up too.

Well, for that particular problem, there is a much simpler solution than splitting application into two distinct processes. It's called multithreading. Moving UI into a separate thread would not only be simpler than moving it into a separate process, but also wouldn't result in 20-50% memory usage growth.



view as:

That's what they're doing now and it's the problem, not the solution.

Multiple threads run in the same process address space. This creates security and stability issues. One website can affect the complete experience. That's exactly the problem they're trying to solve, the same way Chrome did, by using multiple processes. That way, for example, when one process misbehaves and gobbles up too much memory, the OS won't kill the entire browser but just the offending tab. (The OS won't kill individual threads.)


> security and stability

That's shifting goalposts. GP quoted that it's about responsiveness and resource consumption. And resource consumption is obviously lower with multi-threading since more data structures can be shared.


That's not shifting goalposts, that's the goal from the start.

You seem to be throwing a lot of technical terms. Could you elaborate on where exactly do you see overhead coming from in a multiprocess vs. multithread architecture? And which data structures can be shared between threads but not between processes?

Scheduling overhead is identical and pure OS memory overhead is slightly higher for processes (they need more "accounting" data), but everything else can be optimized at the application level. Furthermore, shared memory lets you share data structures between processes just fine (heck, some data can be shared between processes and the kernel!), and since I assume the content processes will be dynamically linked, you're not even going to load shared libraries multiple times.


> shared memory lets you share data structures between processes

In theory maybe. In practice data structures contain pointers, which you can't just shove into cross-process shared memory. Which in turn results in copying things and serialization/deserialization overhead when doing IPC.

With multi-threading you can just share regular data structures (think std::map) and put them under locks or copy-on-write logic if they need to be modified.

Of course you can share some large blobs, like pixel data or loaded files. But the major data churn consisting of many small, nested data structures involves copying and (de)serializing.


The author justifies introduction of e10s using an example of inter-tab CPU contention. Yes, this is a real problem, I experience it using Firefox. But for that particular issue, a sufficient solution is multithreading.

As you wrote, separating each tab into a different process will bring security and stability benefits. But blog post author does not mention any of them. The only justification for e10s he brings up is CPU-UI blocking problem (which is not a justification for e10s at all, because it can be solved with multithreading).

And there is a reason why he doesn't mention security and stability benefits: They do not plan [1] (at least for now) separating each tab into a different process. All tabs will still share the same content process. This means that e10s would not bring any security and stability benefits you wrote about.

So one may ask: what's the point in introduction of e10s at all? I ask myself this question as well, not only regarding e10s, but also many other Mozilla decisions from last few years.

[1]: https://wiki.mozilla.org/Electrolysis/Multiple_content_proce...


They say that they want to move to multiple content processes, so I guess that their end goal is still one content process per tab.

Also, another reason for e10s is to decouple the rendering engine from the UI parts, in order to a) get rid of XUL and b) offer a path for replacing Gecko with Servo once Servo's ready for primetime.


> a) get rid of XUL

And the same time break tens thousands of extensions (which are the main reason why most Firefox users still use this browser).


Have you ever seen the source base of a browser like Firefox or Chrome? You must do small incremental improvements if you want your software to continue to work. The hardest part is disentangling everything from a single process architecture to multiprocess. That's what they're doing now. Switching from a single content process to multiple content processes is significantly easier.

I don't understand how you conclude that "they do not plan separating each to into a different process" from the link you posted given it opens with "After e10s is enabled for all users, the next step is to introduce multiple content processes." To answer your question, then, the point of introducing e10s is to make it easier to switch from a single process to multiprocess architecture.


Yes, but few lines below they wrote: "The (practically) unlimited process count is on some platforms not a realistic goal, and having a separate process for each open site instances or even sites does not seem like a reachable goal (for now at least)."

So per-tab content processes (which btw is the only way e10s can result in security and stability benefits) is not a realistic goal for them.


Technically speaking, it's a lot easier to do a separate process per tab, and let things crash just like any other running process. If they don't stop there and try to actually manage processes by themselves according to some messed up logic, then yes, I agree with you that there's no point to e10s and probably Mozilla.

> and let things crash just like any other running process

People always say that as if crashes would be a regular thing happening every few minutes. I don't experience browser crashes for days, so I find it kind of odd that such a relatively rare failure case is considered a good justification for using a process per tab.


I stopped using Chrome a couple of years ago because of multiple crashes per day. The browser itself didn't crash, but individual tabs did. Or else Chrome tabs failed to load (giving just a pale blue background) presumably because it had run out of RAM.

I used OneTab for a while, to reduce memory use, but still found Firefox more efficient and more stable with hundreds of tabs, mainly because the vast majority weren't actually loaded until I needed them.

It's not hard to crash Firefox -- just keep loading an infinite page of gifs etc. But once you know that, you don't do it.

Under normal working conditions, I agree: none of the main browsers crashes often enough for it to be a problem.


I'm not aware of any browser that implements "per-tab content processes". For example, Chrome caps the number of content processes and multiple tabs in Chrome start sharing the same content process once enough tabs are open.

e10s will bring some security and stability benefits. If one webpage crashes, all webpages crash, but you can click to reload. Additionally, this enables sandboxing, so that code from webpages can be run with lower levels of access. Sure, it is not perfect, but it is a large improvement from the status quo.

(Even process-per-tab is not perfect for security: a compromised page from one origin could open an iframe to another origin.)


If you're saying that splitting UI and content into different processes is different from splitting the two up into different threads, could you explain how that is different? I am especially interested in how it results into a 20-50% memory usage growth, especially now that memory usage by browsers is a hot topic.

I just don't why you consider that to be more simple...

IPC is more complex than coordinating threads.

That's false.

IPC, shared memory, and credentials/descriptor passing are common patterns that exist in tons of software today. OpenSSH, Postfix, probably every iOS app.

Multithreading is great, but it's not suitable for a browser that may be fed malicious code and has a huge attack surface.


Those mechanisms existing does not prove that they have zero overhead and complexity increases over multi-threading.

To add more of an explanation to your comment.

Yes, in those simple terms, it would be 1) simpler to coordinate multiple threads in the same process compared to multiple processes, and 2) more efficient too.

1 is true because any system you might use to communicate between processes would involve an IPC layer and with a single process, you could use an identical system with the IPC removed.

2 is true because multiple threads in the same process can communicate directly without requiring IPC (which requires data serialization, shared memory for performance, and more system calls). i.e, sharing data has much higher cost using IPC. You can skip some serialization if you use shared memory, but you still need to set that up and manage shared buffers. (Different applications might share data in different ways so that the IPC overhead becomes negligible, but non-IPC could always be implemented faster.)

But the benefit gained from using multiple processes for a web browser (that is essentially a VM for running untrusted JS/web code) is security in the face of bugs. It comes from how operating systems provide tried-and-tested process isolation. If sites from separate origins are rendered or parsed in their own process, some types of browser bugs are harder to exploit to gain access to data from other origins. And for bugs that just cause crashes without security implications, you can crash a single tab and let other tabs continue, let the main UI continue.

On its own, that is good, but not great.

The big benefit is that the big 3 operating systems that browser developers are concerned with provide some level of per-process sandboxing. For example, one can launch a process with a limited set of privileges such that the only thing that process is allowed to do is communicate via IPC and compute stuff. The operating system enforces this for you. Provided you have a strong IPC layer, a process with such limited privileges can do very little damage if it is compromised.

Developing a strong IPC layer is not extremely difficult as it essentially boils down to reading a stream of messages from an untrusted source and detecting invalid messages without compromising yourself.


I'm aware of all those things, but look up-thread to see that this was about the performance and resource consumption argument where multi-process is the inferior choice, that's what this argument is about.

> And for bugs that just cause crashes without security implications, you can crash a single tab and let other tabs continue, let the main UI continue.

That's using non-security bugs as an argument for increasing memory footprint. It would be preferable to have those bugs fixed instead.

> Developing a strong IPC layer is not extremely difficult as it essentially boils down to reading a stream of messages from an untrusted source and detecting invalid messages without compromising yourself.

That's implementation complexity. But you also have to consider the performance overhead of proxying method access to arbitrary objects and bouncing each method invocation and its results back and forth. That's needed for backwards compatibility with addon code unaware of the process separation.

https://developer.mozilla.org/en-US/Firefox/Multiprocess_Fir...


Also the main process doesn't actually stay responsive for me with E10S, but I suppose I should try with extensions disabled.

An experimental investigation into a multithreaded model (for UI and webpages) was investigated a few years ago (see https://bugzilla.mozilla.org/show_bug.cgi?id=718121 ), and I don't think it looked to be "much simpler". The major problem with moving to multiple processes is that JS running the UI has to be adapted to dealing with page JS that is "somewhere else". Because the JS execution model is based on a single thread, I don't think it would be so much easier to deal with JS on another thread than in another process. Requiring multiple JS runtimes would likely also increase memory usage even in a multithreaded model, though it does seem like it would be less than e10s.

Legal | privacy