Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENTER_FRAME listener on class appears to keep class allocated in memory #273

Open
mayorbyrne opened this issue Apr 20, 2017 · 4 comments
Open

Comments

@mayorbyrne
Copy link

Consider the following code:

import 'package:stagexl/stagexl.dart';

class TestEnterFrame extends Sprite
{
  Sprite _bg;
  TestEnterFrame()
  {
    _bg = new Sprite()
      ..graphics.rect(-400, 0, 600, 100)
      ..graphics.fillColor(Color.Green)
      ..useHandCursor = true
      ..addTo(this);

    this.addEventListener(Event.ENTER_FRAME, _enterFrame);
  }

  void _enterFrame(Event event)
  {
    print('entered frame');
    return;
  }

  void dispose()
  {
    print(this.hasEventListener(Event.ENTER_FRAME)); // true
    print('removing event listener');
    this.removeEventListener(Event.ENTER_FRAME, _enterFrame);
    print(this.hasEventListener(Event.ENTER_FRAME)); // false
    this.removeChildren();
  }
}
TestEnterFrame _test;

void main() {
  ...
  ...
  ...
  _test = new TestEnterFrame()
    ..addTo(stage);

  _test.addEventListener(MouseEvent.CLICK, _interact);
}

_interact(Event event)
{
  _test.removeEventListener(MouseEvent.CLICK, _interact);
  _test
    ..dispose()
    ..removeFromParent();
  _test = null;
}

Once the TestEnterFrame sprite has been clicked and _interact has fired, I try running a manual garbage collection, and the TestEnterFrame class remains allocated in memory.

However, it appears to be properly released from allocation if I instead attach the ENTER_FRAME listener to the _bg sprite of the class.

Any information would be greatly appreciated!

@bp74
Copy link
Owner

bp74 commented Apr 20, 2017

Hi, this may be because the ENTER_FRAME event is a special kind of event listener. Every time you register such an event listener, the event listener is not only registered in EventDispatcher (base class of DisplayObject) but also in a global list of event listeners. This is necessary to call all ENTER_FRAME listeners efficently, otherwise we would need to iterate over all DisplayObjects in the display list to find those who have such an event listener registered.

The CLICK event listener is different. It is only registered in the EventDispatcher (base class of DisplayObject).

However, if you call removeEventListener for the ENTER_FRAME event listener it should be removed from the global list too. And therefore should be garbage collected.

I need to take a closer look at this, please give me 2-3 days to get back to you.

@bp74
Copy link
Owner

bp74 commented Apr 22, 2017

Okay i played a little bit with your example. When you say that the TestEnterFrame object is not released, do you mean that you still see it allocated in memory? Did you test this with the developer tools of the browser?

The example works as expected right? It's just the thing with the memory. Probably it is just the way how the garbage collector works. Even if you set the _test variable to null, it does not mean that the garbage collector immediately removes the object from memory. If there is no pressure to release allocated memory, the garbage collector will do nothing. Only after a while the GC will kick in an release all objects that are not referenced any more.

Please let me know if this helps or if i miss something here.

@mayorbyrne
Copy link
Author

mayorbyrne commented Apr 24, 2017

I am forcing garbage collection through Dartium's observatory by clicking the GC button in Allocation Profile. When the enter_frame listener is not on this, but rather on the _bg sprite, the allocated instances of TestEnterFrame correctly goes down to 0 after a GC/refresh. If the enter_frame listener is added to this, the allocated instances of TestEnterFrame remains at 1 after a GC/refresh.

@bp74
Copy link
Owner

bp74 commented Apr 25, 2017

I will try that and keep you posted!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants