repeated attribute changes lead to infinite rule tree growth

RESOLVED FIXED in mozilla1.4alpha

Status

()

Core
CSS Parsing and Computation
P1
major
RESOLVED FIXED
16 years ago
3 years ago

People

(Reporter: Markus Hübner, Assigned: dbaron)

Tracking

(Depends on: 1 bug, {mlk, perf, testcase})

Trunk
mozilla1.4alpha
mlk, perf, testcase
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [patch], URL)

Attachments

(2 attachments, 7 obsolete attachments)

(Reporter)

Description

16 years ago
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.
(Reporter)

Updated

16 years ago

Comment 1

16 years ago
Confirming on Linux 2001122821. Memory usage growth stops after closing window.

Comment 2

16 years ago
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

Comment 3

16 years ago
Created attachment 63013 [details]
Reduced testcase

setAttribute("width") and ("height") seem to be the cause of this problem.
Does adding |var widthHeight;| in global scope help?
(Assignee)

Comment 5

16 years ago
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

Comment 6

16 years ago
-- Does adding |var widthHeight;| in global scope help?

No



(Assignee)

Comment 7

16 years ago
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|.
(Assignee)

Updated

16 years ago
Summary: Memory usage skyrocketing → repeated attribute changes lead to infinite rule tree growth
(Reporter)

Updated

16 years ago
Blocks: 92580
(Reporter)

Updated

16 years ago
Keywords: mozilla0.9.8

Updated

16 years ago
Keywords: mozilla0.9.9
(Reporter)

Updated

16 years ago
Keywords: mozilla1.0

Updated

15 years ago
Keywords: mozilla1.0+

Updated

15 years ago
Keywords: mozilla1.0
Keywords: mozilla0.9.8, mozilla0.9.9 → testcase
(Assignee)

Comment 8

15 years ago
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.
(Assignee)

Comment 9

15 years ago
...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.
(Assignee)

Comment 10

15 years ago
When we remove a rule node we'll need to clear the mapping in the style set
added for bug 99344.
(Assignee)

Comment 11

15 years ago
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
(Reporter)

Comment 12

15 years ago
*** Bug 142528 has been marked as a duplicate of this bug. ***

Comment 13

15 years ago
 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.
(Reporter)

Updated

15 years ago
Hardware: PC → All

Comment 14

15 years ago
  This error caused by the javascript in the html file. The IE have the same 
result.

  -> won't fix
  
  I suggest to close it.
(Reporter)

Comment 15

15 years ago
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.
(Assignee)

Comment 16

15 years ago
This should be fixed at some point.

Comment 17

15 years ago
   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?
(Assignee)

Comment 18

15 years ago
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.

Comment 19

15 years ago
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
(Reporter)

Comment 20

15 years ago
"Go to the URL and select 1 in the dropdown"
where is that ?

Comment 21

15 years ago
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. 
(Reporter)

Comment 22

15 years ago
I see heavy frame-drop offs on http://www.formula-one.nu/dhtml/3d.htm
see bug 157401.

(Reporter)

Updated

15 years ago
Keywords: mozilla1.2
Depends on: 166450
Blocks: 166298
(Assignee)

Updated

15 years ago
Target Milestone: mozilla1.2alpha → Future
(Assignee)

Updated

15 years ago
Priority: P3 → P1

Updated

15 years ago
Keywords: nsbeta1
(Reporter)

Comment 23

15 years ago
Bug 166298 seems also related to this.
(Assignee)

Comment 24

15 years ago
*** Bug 166298 has been marked as a duplicate of this bug. ***

Updated

15 years ago
Keywords: mozilla1.3
(Reporter)

Updated

15 years ago
Keywords: mozilla1.2
(Assignee)

Updated

15 years ago
Blocks: 188803
(Reporter)

Comment 25

15 years ago
The 3D Demo is now at 
http://www.world-direct.com/mozilla/dhtml/3dcube/index.htm
just 4 info :)

(Assignee)

Updated

15 years ago
Target Milestone: Future → mozilla1.4alpha
(Assignee)

Comment 26

15 years ago
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.
(Assignee)

Comment 27

15 years ago
Created attachment 113465 [details] [diff] [review]
patch (untested)

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.
(Assignee)

Comment 28

15 years ago
Created attachment 113496 [details] [diff] [review]
patch (untested)

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...
(Assignee)

Comment 30

15 years ago
Created attachment 113514 [details] [diff] [review]
patch (untested)

Yep.  I even said I'd do that in nsRuleNode.h.
Attachment #113496 - Attachment is obsolete: true
(Assignee)

Comment 31

15 years ago
Created attachment 113515 [details] [diff] [review]
patch (untested)

Return too.
Attachment #113514 - Attachment is obsolete: true
(Assignee)

Comment 32

15 years ago
Created attachment 114148 [details] [diff] [review]
patch

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
(Assignee)

Updated

14 years ago
Whiteboard: [patch]
(Assignee)

Comment 33

14 years ago
Created attachment 115396 [details] [diff] [review]
patch

merged to tip
Attachment #114148 - Attachment is obsolete: true
(Assignee)

Comment 34

14 years ago
Created attachment 115409 [details] [diff] [review]
patch

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

Comment 35

14 years ago
*** 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?
(Assignee)

Comment 37

14 years ago
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.
(Assignee)

Comment 39

14 years ago
Created attachment 116400 [details] [diff] [review]
patch

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
(Assignee)

Updated

14 years ago
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+
(Assignee)

Comment 41

14 years ago
Fix checked in to trunk, 2003-03-06 11:14 PST (with bustage fix at 12:16 PST).
Status: ASSIGNED → RESOLVED
Last Resolved: 14 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.