Closed Bug 117316 Opened 23 years ago Closed 22 years ago

repeated attribute changes lead to infinite rule tree growth

Categories

(Core :: CSS Parsing and Computation, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.4alpha

People

(Reporter: markushuebner, Assigned: dbaron)

References

()

Details

(Keywords: memory-leak, perf, testcase, Whiteboard: [patch])

Attachments

(2 files, 7 obsolete files)

1. just go to http://www.formula-one.nu/dhtml/3d.htm 2. open the taskmanager 3. look at mozilla's memory usage - increasing about 300kb/sec ! memory usage will continue growing forever w/o never decreasing. Verified using 0.9.7 and build 2001122803 on win2k and win-xp.
Confirming on Linux 2001122821. Memory usage growth stops after closing window.
Also on Linux 2001122608. If I stop close the window and reopen it, it takes a while for the memory usage to grow.
OS: Windows 2000 → All
Attached file Reduced testcase (deleted) —
setAttribute("width") and ("height") seem to be the cause of this problem.
Does adding |var widthHeight;| in global scope help?
The main sources of increase are the following: 18675361 malloc 17746654 PR_Malloc 17453053 PL_ArenaAllocate 17505210 FrameArena::AllocateFrame(unsigned int, void **) 17505210 PresShell::AllocateFrame(unsigned int, void **) 17496980 nsPresContext::AllocateFromShell(unsigned int, void **) 5411225 nsResetStyleData::operator new(unsigned int, ... 3962745 nsStyleBorder::operator new(unsigned int, nsIPresContext *) 3168550 nsInheritedStyleData::operator new(unsigned int, ... 1555470 nsRuleNode::operator new(unsigned int, nsIPresContext *) 1390870 nsStyleDisplay::operator new(unsigned int, nsIPresContext *) 921760 nsRuleList::operator new(unsigned int, nsIPresContext *) 609020 nsStylePosition::operator new(unsigned int, nsIPresContext *) 489685 nsShellISupportsKey::operator new(unsigned int, ... 585728 /builds/trunk/obj/debug/dist/bin/libxpcom.so+9585D 585728 PL_HashTableRawAdd 585728 nsHashtable::Put(nsHashKey *, void *) 622496 nsRuleNode::Transition(nsIStyleRule *, nsRuleNode **) 622496 nsRuleWalker::Forward(nsIStyleRule *) 2116207 __builtin_new 2016404 nsHTMLMappedAttributes::Clone(nsHTMLMappedAttributes **) const 2016404 HTMLAttributesImpl::EnsureSingleMappedFor(nsIHTMLContent *, ... 2016404 HTMLAttributesImpl::SetAttributeFor(nsIAtom *, ... 2016404 HTMLStyleSheetImpl::SetAttributeFor(nsIAtom *, ... 2016404 nsGenericHTMLElement::SetHTMLAttribute(nsIAtom *, ... 1238368 HTMLAttribute::CopyHTMLAttributes(HTMLAttribute *, HTMLAttribute **) 1238384 nsHTMLMappedAttributes::nsHTMLMappedAttributes(... 1238384 nsHTMLMappedAttributes::Clone(nsHTMLMappedAttributes **) const 1238384 HTMLAttributesImpl::EnsureSingleMappedFor(... 1238384 HTMLAttributesImpl::SetAttributeFor(nsIAtom *, ... (These numbers may be a bit skewed since my second log was truncated since my disk filled up.) Looks like rule tree growth, which is basically as-designed, since we want reresolution to be fast, but perhaps we need to remove parts of the rule tree when rules are removed? I'm not really familiar with how the mapped attributes stuff works, though.
Component: Browser-General → Style System
-- Does adding |var widthHeight;| in global scope help? No
One possible solution (I think) would be to add a method |IsLive| to |nsIStyleRule| and every time 1000 (or some large number) of rule nodes are added to the rule tree, sweep the rule tree and remove all branches containing nodes that are not live. I *think* such a method could be implemented on |nsHTMLMappedAttributes|, using its |mUseCount|.
Summary: Memory usage skyrocketing → repeated attribute changes lead to infinite rule tree growth
Blocks: 92580
Keywords: mozilla0.9.8
Keywords: mozilla0.9.9
Keywords: mozilla1.0
Keywords: mozilla1.0+
Keywords: mozilla1.0
The other thing such a solution would allow is keeping full rebuilds of the rule tree rarer -- we could just do a sweep of the rule tree after a stylesheet remove that would remove all rule nodes pointing to a rule node whose rule was in a stylesheet that was no longer active.
...then again, that would cause a performance hit if a stylesheet were removed and readded repeatedly. But maybe that's rare enough that we don't care.
When we remove a rule node we'll need to clear the mapping in the style set added for bug 99344.
Does anybody really think this should be fixed for 1.0? I never did, since it involves pretty major changes.
Status: NEW → ASSIGNED
Priority: -- → P3
Target Milestone: --- → mozilla1.2alpha
*** Bug 142528 has been marked as a duplicate of this bug. ***
I watch too many frames produced by the js. Edit-->Preferences-->Debug-->Event and select show frames, clich OK Use the Reduced testcase, you will watch the frames' number become larger and larger so fast.
Hardware: PC → All
This error caused by the javascript in the html file. The IE have the same result. -> won't fix I suggest to close it.
Using MSIE6 the memory consumption remains exactly the same all over the animation! Using trunk build 2002062308 the memory consumptions goes up rapidly - as already said abour 300kb/sec.
This should be fixed at some point.
If it is a bug really,it caused by reflow process, because the frame number increase continuely and not decrease. The "reduced testcase" draw a rectangle ceaselessly, so it can produce many many frames and take much memory. who can tell me the life cycle of a frame? I want to release the frames in time. With the reduced testcase, The IE will take 100% cpu, but I takes little mem, I think it has a good garbage collector. If i can release the mem fastly, mozilla can work as IE. David Baron: could you give me some suggestions?
This has nothing to do with reflow, it has to do with the rule tree. I understand what it is and I'm planning to fix it one of these days.
Go to the URL and select 1 in the dropdown. The animation is soo awful that it kind of reminds of bug 129953. Anyone else? Using build 20020704 on Windows 2000
"Go to the URL and select 1 in the dropdown" where is that ?
On this link: http://www.formula-one.nu/dhtml/moz3d.htm Select 1 in the select box, if you dont see what I mean, then bring up the windows task manager and then close it.
I see heavy frame-drop offs on http://www.formula-one.nu/dhtml/3d.htm see bug 157401.
Keywords: mozilla1.2
Depends on: 166450
Blocks: 166298
Target Milestone: mozilla1.2alpha → Future
Priority: P3 → P1
Keywords: nsbeta1
*** Bug 166298 has been marked as a duplicate of this bug. ***
Keywords: mozilla1.3
Keywords: mozilla1.2
Blocks: 188803
Target Milestone: Future → mozilla1.4alpha
I hacked up a patch for this that I'll attach shortly. I haven't attempted to compile it yet, and I won't until I'm able to land some of the things I have in my existing compiling trees and free up some build space. Note that there is a circular dependency between this patch and bug 171830 (see the XXX comment in this patch). I believe there would be some crashes if this patch lands before bug 171830 because of stale info in the rule mappings table. Likewise, bug 171830 needs to land at the same time as this one or else we'll have significant memory increases in significantly more cases.
Attached patch patch (untested) (obsolete) (deleted) — Splinter Review
Untested. Not even compiled. Don't try this at home. It won't compile. And if it does it will crash. Like I said in the previous comment, I'll finish this once I clean out some of my trees.
Attached patch patch (untested) (obsolete) (deleted) — Splinter Review
Still untested, but a bunch of major errors now fixed.
Attachment #113465 - Attachment is obsolete: true
Before you test, add mDependentBits &= ~NS_RULE_NODE_GC_MARK; to Sweep() somewhere. Looking pretty good otherwise...
Attached patch patch (untested) (obsolete) (deleted) — Splinter Review
Yep. I even said I'd do that in nsRuleNode.h.
Attachment #113496 - Attachment is obsolete: true
Attached patch patch (untested) (obsolete) (deleted) — Splinter Review
Return too.
Attachment #113514 - Attachment is obsolete: true
Attached patch patch (obsolete) (deleted) — Splinter Review
This compiles, runs, and prevents memory use from increasing while displaying http://www.world-direct.com/mozilla/dhtml/test.html
Attachment #113515 - Attachment is obsolete: true
Blocks: 193275
Whiteboard: [patch]
Attached patch patch (obsolete) (deleted) — Splinter Review
merged to tip
Attachment #114148 - Attachment is obsolete: true
Attached patch patch (obsolete) (deleted) — Splinter Review
This allows for the fact that there can be multiple style contexts without a parent. I still saw one crash, but I can't reproduce it. (I also have a version merged with bz's patch to bug 171830.)
Attachment #115396 - Attachment is obsolete: true
*** Bug 195408 has been marked as a duplicate of this bug. ***
David, are you happy enough with that patch that you want reviews for it? Or are you still testing?
Well, I was playing around with a tree that had it and bug 171830 merged in a single tree. I crashed. I looked at the stack quickly in the debugger, thought I knew what was going on, quit the debugger, went to fix the code, and the problem I thought was there didn't exist. And I haven't been able to reproduce the crash since. I guess there's a chance the problem could be unrelated, but it seems unlikely. I guess you could review, though, and hopefully we'll find the crash later?
Comment on attachment 115409 [details] [diff] [review] patch >+PRBool >+nsRuleNode::Sweep() OK, so Sweep() will Destroy() the rulenode and return PR_TRUE if it was destroyed... >+ if ((*children)->mRuleNode->Sweep()) { >+ // This rule node was destroyed, so remove this entry, and >+ // implicitly advance by making *children point to the next >+ // entry. >+ nsRuleList *todestroy = *children; >+ *children = todestroy->mNext; >+ todestroy->mNext = nsnull; >+ todestroy->Destroy(mPresContext); and this will call nsRuleList::Destroy which will turn around and call Destroy() on its mRuleNode _again_ and then wipe out the rest of the list (neither of which is desirable as far as I can tell). Shouldn't that be a call to DestroySelf instead? Like: *children = (*children)->DestroySelf(mPresContext); instead of those four lines of code? (Now why didn't I read the definition of Destroy() the forst time I read this patch? <sigh>) This seems like a reasonable candidate for that crash you were seeing..... >+NS_IMETHODIMP >+StyleSetImpl::NotifyStyleContextDestroyed(nsIPresContext* aPresContext, >+ nsStyleContext* aStyleContext) >+{ This should check mInShutdown and return without doing anything if that's set, right? Looks pretty good other than those two issues.
Attached patch patch (deleted) — Splinter Review
I haven't tested this yet, but it fixes the problems bz pointed out, plus a missing return and the removal of the comment that won't be needed once bug 171830 lands.
Attachment #115409 - Attachment is obsolete: true
Attachment #116400 - Flags: superreview?(bzbarsky)
Attachment #116400 - Flags: review?(bzbarsky)
Comment on attachment 116400 [details] [diff] [review] patch Good catch on the return... (and on clearing mRoots when we start shutting down). r+sr=bzbarsky
Attachment #116400 - Flags: superreview?(bzbarsky)
Attachment #116400 - Flags: superreview+
Attachment #116400 - Flags: review?(bzbarsky)
Attachment #116400 - Flags: review+
Fix checked in to trunk, 2003-03-06 11:14 PST (with bustage fix at 12:16 PST).
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: