[MTOS-dev] Circular reference issue
Hirotaka Ogawa
hirotaka.ogawa at gmail.com
Wed Jan 16 10:55:21 PST 2008
On Jan 16, 2008 12:56 PM, Timothy Appnel <tim at appnel.com> wrote:
> Someone at Six Apart is going to owe Hirotaka and I several adult
> beverages of our choice.
Ha ha, I like California wines, especially Dominus Estate wines. Does
anybody take my order?
> I picked up where Hirotaka left off looking for why so many
> MT::Template::Node objects are left at the end of a page build. After
> several hours I should have been spending on other work I made an
> interesting discovery though I'm not 100% sure what it means.
>
> I need to stop here and will be tied up most of the day tomorrow that
> I thought I'd better report what I've found in the hope it helps the
> next person figure out where to look next.
>
> After apply Hirotaka's patches to the release 1240 (current dev
> release when I started), I began experimenting with DESTROY methods
> that traversed the tree calling the DESTROY method on its children
> before blanking its own internal memory. Nothing I did cleared up
> those nodes that were hanging out. I even inserted debugging messages
> that showed that these DESTROY methods where getting called. The still
> persisted.
>
> This led me to wonder if nodes where being created without a parent
> relationship or where the node had a parent, but the parent had
> disowned the child. Parsing the default main index yielded 47 nodes
> that did not have a parent defined. In a quick glance of the data dump
> most, but not all, of these nodes had children.
>
> So my theory is that some of these nodes that are collecting is
> because whole branches are somehow being disowned from their roots
> with circular references still entact. I'm not 100% sure that is
> correct though, but that is my hunch at the moment.
>
> The nodes without children are what puzzle me at the moment. Why
> aren't those falling out of scope? I'm using weakened references to
> build my tables and know that some references I stored there are
> undefined by the time I run the dump.
Now I suppose I can explain why so many objects are being alive.
Some methods in ContextHandlers.pm stash the internal data including
MT::Template instances and entry tags, into MT::Request->instance, in
order to reuse them and speed up next building. Therefore, this
stashing feature itself is harmless as far as the size of stashed
objects keeps constant for every request. As you know, you can insert
the following lines at the end of t2.pl and see which data remains in
MT::Request->instance:
use Data::Dumper;
print Dumper(MT::Request->instance);
Next I tried to add MT::Request->finish() just before exiting the
testing code (t2.pl), in order to destroy all MT::Request contents.
But it does not always work well.
The reason is a little complicated, but assuming that
MT::Request->instance has an instance named "__stash" which has
several references to MT::Template::Tokens objects, and besides, such
Tokens objects substantially have circular references, we cannot make
the reference counts of Tokens be zero even if we just set
MT::Request->instance to undef. That's why MT::Request->finish()
sometimes fails to destroy MT::Request contents, I suppose.
Instead of MT::Request->finish(), MT::Request->reset() may work well.
t4.pl I've attached is a modified version of t2.pl which calls
MT::Request->reset() at the end of the script.
>From these observations, I've noticed another potential problem, that
is, MT::App::takedown() method just calls MT::Request->finish() to
clean up MT::Request cache. I feel uneasy about the possibility which
this may become another source of orphaned object creation.
> Another curious thing I noticed is that a lot of the parent-less nodes
> with children are the If tag. Perhaps its something in how conditional
> branch tokens are being managed?
>
> I've attached a test script and a patch to MT::Builder that has the
> debugging code needed to collect nodes being created. I also attached
> a log of the last run I did with all the gory details exposed.
>
> This has been really tricky because the compile code is just plain
> nasty. I really have to wonder if it really needs to be that way. I
> just find it hard to believe this couldn't be a lot better organized.
>
> Having nodes being "psuedo objects" without a constructor or methods
> for accessing its parent, children and attributes, really makes
> debugging this sort of thing so much harder since their creation is
> all over the place. It also gets very confusing trying to read through
> the code and pick out where a parent is getting set (array index 5) or
> children are being fetched (array index 2). I recognize that perl
> method calls are slow in comparison to accessing references directly,
> but does it really make THAT big a difference to the system's overall
> performance to lay such a heavy burden on code maintainability?
> Compiling a template seems small in comparison to other operations
> like building the page. I'm just wondering outloud here. It just seems
> a shame that this DOM interface was created and yet the system doesn't
> actually use it.
I agree with this suggestion. In case Six Apart people employ weak
references, it is convenient to encapsulate "weaken codes" into
constructors and/or setter methods.
>
> Hope this was helpful. Carry on.
>
>
> <tim/>
>
> --
> Timothy Appnel
> Appnel Solutions
> http://appnel.com/
>
--
Hirotaka Ogawa makes no sense.
http://as-is.net/blog/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: t4.pl
Type: application/x-perl
Size: 496 bytes
Desc: not available
Url : http://www.sixapart.com/pipermail/mtos-dev/attachments/20080117/e280a2c6/attachment.bin
More information about the MTOS-dev
mailing list