tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/446-systemgc-and-mediator-dispatch-failureRobotlegs: Discussion 2012-01-05T13:00:42Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-02T19:18:42Z2011-12-02T19:18:42ZSystem.gc() and Mediator dispatch failure<div><p>Also I noticed that sometimes it would randomly "unmap" them as
well, with regular GC, while i was using new "gc advice" (which by
the way does not seem very efficient).</p>
<p>namely this command:</p>
<p>System.pauseForGCIfCollectionImminent();</p></div>Rosttag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-04T13:14:30Z2011-12-04T13:14:30ZSystem.gc() and Mediator dispatch failure<div><p>Hi Rost,</p>
<p>That’s an interesting situation!<br>
I’m using System.pauseForGCIfCollectionImminent(0.10); in one
of my AIR applications, and I haven't encountered such a problem
yet. I also tried to call the method at different points in time
and also called System.gc(), but I couldn’t reproduce the
issue. The useWeakReference is by default set to true and I
didn’t change that.<br>
In my opinion forcing the garbage collection shouldn’t affect
your code in unexpected ways, but as we all know
FlashPlayer’s gc is a very strange thing;)</p>
<p>I’m not sure it will help you, but let’s take a look
at how the mappings work.<br>
This:<br>
eventMap.mapListener(eventDispatcher, SomeModelEvent.DATA_UPDATED,
onDataUpdated, SomeModelEvent, false, 0, true);<br>
is the same as adding an event listener to the shared
IEventDispatcher.</p>
<p>This:<br>
eventMap.mapListener(view, SomeViewEvent.NEED_DATA, onNeedData,
SomeViewEvent, false, 0, true);<br>
is the same as registering an event listener object with an
EventDispatcher object (the view component)</p>
<p>As long as eventDispatcher is not null or in the second case the
view is not null, and the handler function isn’t an anonymous
function, the System.gc() won’t affect them.</p>
<p>The “unmapping” doesn’t occur because of the
useWeakReference.<br>
In fact it happens only in 2 circumstances:<br>
- either you do it manually:</p>
<p>eventMap.unmapListener(eventDispatcher,
SomeModelEvent.DATA_UPDATED, onDataUpdated);<br>
eventMap.unmapListener(view, SomeViewEvent.NEED_DATA,
onNeedData);<br>
which rl-internally will result in this:<br>
EventMap.unmapListener(dispatcher, type, listener, eventClass,
useCapture)</p>
<p>-or it happens automatically after the View has been removed
from the display list:</p>
<p>MediatorMap.onViewRemoved()<br>
MediatorMap.removeMediator()<br>
Mediator.preRemove()<br>
EventMap.unmapListener(dispatcher, type, listener, eventClass,
useCapture)</p>
<p>Now let’s look at this:<br>
mediatorMap.mapView(SomeView, SomeMediator, null, true, true);<br>
The last 2 parameters are autoCreate:Boolean and
autoRemove:Boolean, by default set to true.<br>
If autoRemove is set to true then robotlegs will remove the
mediator and remove all listeners registered through its
eventMap.mapListener when its view is removed from stage.</p>
<p>So, I would check if the “unmappings” are related to
Views that have been removed from stage, through drag and drop
actions or changing view’s states or by using something like
a ViewStack.</p>
<p>I’m sure you already know about this:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/Common-Problems#wiki-mysteriously-stops">
https://github.com/robotlegs/robotlegs-framework/wiki/Common-Proble...</a></p>
<p>and this:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/Common-Problems#wiki-event-dispatch-broken">
https://github.com/robotlegs/robotlegs-framework/wiki/Common-Proble...</a></p>
<p>Also, note the last parameter oneshot in
ICommandMap.mapEvent(eventType:String, commandClass:Class,
eventClass:Class=null, oneshot:Boolean=false)<br>
if it is set to true it will unmap the Class after execution</p>
<p>As I said, maybe you already know all this, but I’m
mentioning them just in case;) And also because I don’t know
exactly if you were referring to the eventMap.mapListener or to the
commandMap.mapEvent.</p>
<p>If you still think something is wrong with rl, it would be good
if you could show us a simplified use case where you can reproduce
the issues.</p>
<p>So, since I’m out of ideas maybe someone else can
contribute with more advice about rl and gc.</p>
<p>Ah, here a few links:</p>
<p>Discussions on this forum about gc.</p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/questions/255-lifecycle-of-a-command#comment_2654727">
http://knowledge.robotlegs.org/discussions/questions/255-lifecycle-...</a></p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/questions/127-addeventlistener-in-mediator-with-weak-reference-on-the-view-fails-with-strong-reference-succeedswhy">
http://knowledge.robotlegs.org/discussions/questions/127-addeventli...</a></p>
<p>Here an interesting article about gc:<br>
<a href=
"http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of-useweakreference/">
http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of...</a></p>
<p>I'm interested in hearing about your findings.<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-05T23:10:30Z2011-12-06T09:38:02ZSystem.gc() and Mediator dispatch failure<div><p>Thanks a ton, Ondina, this is very thorough.<br>
My problem as it happens was quite simple and was rooted deep in
the beginning of my development: I did not create a reference to my
context, i just created it as "new" and I guess it was getting
garbage-collected...</p>
<p>So, no I did not see those articles before, although I did check
the rest against it and it seems ok, but this one point helped.
Thanks a lot for all the explaining. As far as unmapping goes, my
breakpoints did not indicate it was happening, so i guess when
context was gone it would stop all bus communication.</p>
<p>PS How do you find System.pauseForGCIfCollectionImminent();
versus System.gc() ?</p>
<p>My app has massive amounts of grapghic data placed and removed
(lists) and the prior method would still not mark or trigger gc for
a lot of items. I was testing using the memory/fps stats monitor i
found on the net (widely used by as3 community), the difference was
huge, in fact with "pauseForGC" it would only clean instances that
were reused (i used object pooling extensively). It may have been
that i got references hanging but then forcing "gc()" wouldn't pick
them up either....On desktop none of this matters but on mobile
memory is of high value....</p></div>Rosttag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-06T11:12:41Z2011-12-06T11:12:41ZSystem.gc() and Mediator dispatch failure<div><p>“Thanks a ton, Ondina, this is very thorough.<br>
My problem as it happens was quite simple and was rooted deep in
the beginning of my development: I did not create a reference to my
context, i just created it as "new" and I guess it was getting
garbage-collected...”</p>
<p>Hey, you’re welcome :)</p>
<p>Sometimes, I like to think of the framework in 2 ways:<br>
-The Context is the Heart of your Application (Body) and the shared
eventDispatcher represents the Vessels, letting the Blood (events,
signals) flow to and from different Organs (Classes), supplying
oxygen and nutrients (Data) to them. Without a heart, the body
dies.</p>
<p>-The Context is the Brain and the shared eventDispatcher is the
nervous system sending signals from one cell to another. Without a
Brain the wiring is broken.</p>
<p>I know, these analogies are a little bit too far-fetched and
there is no one-to-one correspondence between a living organism and
an application;) Anyway, the Context, which is the one providing
the shared eventDispatcher, has to be kept alive and accessible for
the entire application life cycle.</p>
<p>“How do you find System.pauseForGCIfCollectionImminent();
versus System.gc() ?”</p>
<p>I started using System.pauseForGCIfCollectionImminent(); in one
application when it became available, but I’ve never compared
it to System.gc(), so I don’t know which one works better. I
can’t see the source code for those System methods, so I
don’t really know what’s going on behind the scenes.
Something (irrational) is telling me that
System.pauseForGCIfCollectionImminent(); should be the preferred
way.</p>
<p>GC and memory management are complicated matters!!<br>
Here a few links that I found to be useful:<br>
<a href=
"http://forums.puremvc.org/index.php?topic=1291.msg5959#msg5959">http://forums.puremvc.org/index.php?topic=1291.msg5959#msg5959</a></p>
<p>From one of the articles (<a href=
"http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/">http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-coll...</a>)
:<br>
“First off we learned that a call to System.gc() only does a
mark OR a sweep on any given object, but not both in the same call.
So in order to have the effect of releasing memory back to the OS,
we needed to call it twice in a row. One call to mark any
dereferenced objects and sweep away old marks, and the second to
now sweep away marks from the first call.”</p>
<p>Not sure if reading all those articles will help you:)<br>
But if you find a good solution, please let me know about it!</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-07T01:51:11Z2011-12-07T09:44:40ZSystem.gc() and Mediator dispatch failure<div><p>Hey, the analogy is perfect. I wasn't considering "heart" to go
away so easily though, also I other applications i've created
(non-mobile), using RL didn't let "heart " go :).</p>
<p>But anyway, not hard to add another reference.</p>
<p>Big thanks for links, ive seen a bunch of them but some stuff is
the reading i haven't done yet. As far as double gc(), i think its
the thing of the past. Right its working with just a single pass.
I'm tracking this stuff using a variety of memory monitors
including system monitor of the device itself and it does show.</p>
<p>You are correct, the "pause" way is what is promoted as
preferred way by adobe, but for some reason it acts very
differently, and mainly I think because it is not marking objects
aggresively. Even though "pause" method works better then none I'm
going to keep using gc() for now to clean "levels" which I wouldn't
consider an abuse since it happens rarely and mostly (since i use
pooling) to cleanup some previously disposed and nullified
bitmapdata (which i guess i wouldn't need to clean manually but so
far I don't see system doing it for me).</p></div>Rosttag:robotlegs.tenderapp.com,2009-10-18:Comment/118456222011-12-07T12:30:20Z2011-12-07T12:30:20ZSystem.gc() and Mediator dispatch failure<div><p>You’re welcome :)<br>
I’m going to close the thread now. You can re-open it at
anytime, if you want to continue this discussion.</p>
<p>P.S. for some unknown reasons your last 2 posts have landed in
tender’s spam folder and I had to restore them manually in
order to be visible. Maybe the spam filter doesn’t like your
email address ;)</p></div>Ondina D.F.