Closed Bug 399231 Opened 17 years ago Closed 17 years ago

"Recently Closed Tab" feature should be optional and disabled by default due to memory use

Categories

(Firefox :: Session Restore, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: billhigg, Unassigned)

Details

(Whiteboard: [wontfix?])

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

My team has a fairly rich Ajax application, and recently some users have observed that if they don't close Firefox for several days (which is actually quite common), Firefox consumes > 300 MB of RAM, even with only one open tab pointing to the blank page.

My guess is that this is caused by Firefox maintaining a cache of all open pages over the life of the firefox process in order to support the "Recently Closed Tab" feature.

I think "Recently Closed Tab" is a good useful feature, but it's my experience that most people (like 75%) don't know about it, and less use it regularly.  *If* this is the cause of the large memory consumption for long-lived but otherwise empty browsers, I would suggest that it be possible to disable/enable the feature and that by default this feature should be disabled.

The people who don't know / don't use the feature will be unaffected, other than that they consume much less memory. People who know about the feature just need to enable it, and perhaps you can even be tricky and detect whether or not someone has used it and if so, make it default to 'enabled' during an upgrade.

Reproducible: Always

Steps to Reproduce:
1.
2.
3.
Looking at nsSessionStore.js, it looks like the "recently closed tabs" feature uses session history (aka layout history) rather than keeping the entire DOM in memory like the back/forward cache does.  That shouldn't use too much memory per tab, even if it stores the entire history for the tab.  And it's limited to sessionstore.max_tabs_undo tabs (10 tabs).

I doubt the "recently closed tabs" feature is the cause of the high memory usage after a few days of use.  It's more likely to be memory leaks (due to bugs in Firefox or bugs in extensions you use), caching, and malloc fragmentation.  We're working on these issues except for malloc fragmentation; see http://www.squarefree.com/2007/09/20/firefox-memory-usage-and-memory-leak-news/.
Summary: "Recently Closed Tab" feature should be optional and disabled by default → "Recently Closed Tab" feature should be optional and disabled by default due to memory use
Indeed, per default we really just store the URL history of the 10 most recently closed tabs (not even POSTDATA streams which in a few edge cases might add up to a few 100 KB of data) which at worst requires a few dozen KB per window.

If you're not convinced, just set the hidden pref browser.sessionstore.max_tabs_undo to 0 (effectively disabling the feature) for those users observing high memory usage and verify that the issue hasn't been solved at all.

Without further indication that this feature might actually be responsible, this bug would thus be WORKSFORME for the "making optional" part and WONTFIX for the "disabling" part of this bug.
Component: History → Session Restore
QA Contact: history → session.restore
Whiteboard: [wontfix?]
Jesse and Simon, thanks very much for the explanation of how 'Recently Closed Tabs' is implemented and for explaining that it's not the culprit for the high memory consumption after several hours or days of using Firefox. As I said, I was just guessing.

Jesse's web page was especially useful and I was encouraged but not surprised to see that other developers have the same concerns and that the Firefox development team and community is actively addressing the memory usage issue in Firefox 3.

I'll close this bug as WORKSFORME.

Thank you again for the explanations.

PS - Is there anything I, as a web page developer, can do to help Firefox consume less memory, assuming I still want to provide rich, active Ajax pages?  E.g. I was thinking of recursively destroying every DOM node in my Ajax application on page unload, but I'm not sure if this help (or simply cause a slower page unload).
Status: UNCONFIRMED → RESOLVED
Closed: 17 years ago
Resolution: --- → WORKSFORME
> PS - Is there anything I, as a web page developer, can do to help Firefox
> consume less memory, assuming I still want to provide rich, active Ajax pages? 

For keeping memory use down while users are still on your page, you mainly need to avoid holding onto objects longer than needed.  Use JavaScript strict mode so you notice if your code accidentally creates global variables.  Null out large global variables when you're done with them.  Be careful with closures.  (Firefox actually makes this easier than Internet Explorer.  If I understand correctly, IE expects you to manually break cycles between DOM and JavaScript objects.)

For keeping memory use down after users leave your page... use a trunk build of Firefox and help test for leak bugs using leak-gauge.pl or trace-refcnt? :)

> E.g. I was thinking of recursively destroying every DOM node in my Ajax
> application on page unload, but I'm not sure if this help (or simply cause a
> slower page unload).

I don't think unlinking the DOM nodes with removeChild would help.  Firefox still has to run a garbage collection for the nodes to actually be destroyed.  And recursing through your DOM during unload might cause an annoying 1-second hang just as you leave your page, as well as breaking bfcache.
> Null out large global variables when you're done with them.

We follow the pattern where we only create a single global object right after page load and then create other objects as properties of the single global. Do you think it would help to null out our single global object on page unload?

> Be careful with closures.

:-)

Though I know you're not saying this, the above statement reminded me of some "guidance" from the IE team blog. Their variation of "Be careful with closures" was "Avoid Closures if Possible". The feedback on this suggestion from the JS community was (suprise!) not positive:
http://blogs.msdn.com/ie/archive/2007/01/04/ie-jscript-performance-recommendations-part-3-javascript-code-inefficiencies.aspx

> And recursing through your DOM during unload might cause an annoying
> 1-second hang just as you leave your page, as well as breaking bfcache.

Your point regarding bfcache is well-taken, but in our case we're already hosed w/r/t bfcache; the reason for this involves a design trade-off we're willing to live with.
> We follow the pattern where we only create a single global object right after
> page load and then create other objects as properties of the single global.

In that case, you want to null out properties that you're no longer using, especially ones that might entrain lots of objects, so those objects can be collected.

Btw, this pattern means using JavaScript strict mode will have few "false positives" where the creation of the global variable from within a function was actually intentional :)

> Do you think it would help to null out our single global object on page unload?

It might get GCed slightly earlier if you do that (I'm not sure on the details of what's GCed and what's cycle-collected instead), but it shouldn't really matter.
> For keeping memory use down after users leave your page... use a trunk
> build of Firefox ...

I think this is actually the answer to my problem.

I just ran a simple memory usage smoke test using both Firefox 2.0.0.7 (Windows) and Gran Paradiso Alpha 8 (Windows).

Smoke test was:
1) Go to our Ajax web UI
2) Go to www.google.com
3) Repeat steps 1 and 2 ten times

After this smoke test, I saw the following memory usage:

Firefox 2.0.0.7: 65 MB
Gran Paradiso Alpha 8: 42 MB

Note also that Firefox 2 was still increasing ~800k every iteration, whereas Gran Paradiso jumped quickly to 40 MB and then floated between 40 - 42 MB for the duration of the smoke test.

Net: Things are looking very positive on the memory usage front with FF 3. Thanks very much for your efforts.
You need to log in before you can comment on or make changes to this bug.