ReflectionPool - static reference loss on Android?

Anything libgdx related goes here!

ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 2:16 am

I have noticed that using the back key to exit an app on Android is kind of a soft exit, the app is disposed, but when it is reopened it will open much faster than usual, I presume because it reuses the memory that was previously allocated to it? Anyway, my app seems to relaunch fine, except for any objects that I obtain from a ReflectionPool (using Pools.obtain<T>). I am using this method because I do not know the class type for the objects I am creating/reusing. I can get around this in several ways, but it is much cleaner to use the provided tools.

I just wondered if this is the case anyway, or I have done something else wrong. I noticed that the created reflection pools are stored in a static array in the Pools class, is this just getting lost during this type of reset?
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Re: ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 2:52 am

I just cloned Pools class and made it an instance rather than static, and this has fixed the issue. I am curious though if this is actually the issue, or something else I have done is causing it, such as creating my own leaky references to those objects. I don't think I have though!
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Re: ReflectionPool - static reference loss on Android?

Postby shatterblast » Wed Apr 17, 2019 3:19 am

graham01 wrote:I just cloned Pools class and made it an instance rather than static, and this has fixed the issue. I am curious though if this is actually the issue, or something else I have done is causing it, such as creating my own leaky references to those objects. I don't think I have though!

I remember way back reading in Google's Android documentation that most uses of static variables lead to memory leaks. Unfortunately, I am not aware of the exceptions to that rule. AssetManager works fine for me in most cases.
shatterblast
 
Posts: 368
Joined: Sun Jul 06, 2014 1:14 pm

Re: ReflectionPool - static reference loss on Android?

Postby tomski » Wed Apr 17, 2019 8:22 am

You didnt say what your actual problem is? Statics on android will persist past the lifetime of your app. So on next launch they can have the same values as they did previously.

What is your actual issue you are facing regarding Pools? This is used internally by LibGDX in many places, and there is no issue here, so its probably some specific use case you are doing, but without info can't really say.
tomski
 
Posts: 897
Joined: Wed Jun 26, 2013 6:06 pm

Re: ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 11:24 am

I'm pooling drawable Actors that have reference to my main texture atlases. During this type of app restart, those actors will just draw black or corrupted shapes, so it seems they are lingering in the pool over the restart and their reference to the texture atlases are broken (because they are recreated on launch). I could free them on dispose, but that means dragging a dispose method though my source tree, plus it just seems like a bit of a work around. I think Gdx should flush the reflection pools itself on dispose?
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Re: ReflectionPool - static reference loss on Android?

Postby tomski » Wed Apr 17, 2019 12:04 pm

That sounds like a misuse, why do your drawables need reference to the atlas? Just create regions and store them properly. Why are you recreating your atlases too? Just let the lifecycle handle it. Im guessing you have statics for assets somewhere?
tomski
 
Posts: 897
Joined: Wed Jun 26, 2013 6:06 pm

Re: ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 12:37 pm

I mean the Drawables are from my main atlases (Such as SpriteDrawable > Sprite > Texture Region > Texture) It's all pure Gdx and I haven't messed with it and it's all handled by AssetManager. What I'm trying to say is my Actors don't own the root textures, which is how it should be. And what I mean by recreating the atlases is the lifecycle itself. When the app is reopened, AssetManager rebuilds the atlases, so previous references in any leaky static objects are broken.
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Re: ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 1:04 pm

Here's a simple test to demonstrate, tested using 1.9.10-SNAPSHOT, 1.9.9 and 1.9.8. I am using VisUI here for simplicity, but the same applies without VisUI. You will see that the labels disappear if you re-open the app after it was exited using the back key. The issue seems to be that the static reflection pool array in Pools does not get cleared, so calling obtain() will fetch previous leaky objects with broken references.

Code: Select all
public class LeakyPoolsTest extends ApplicationAdapter {

    private Stage stage;
    private VisLabel label1, label2;

    @Override
    public void create() {
        super.create();
        if(!VisUI.isLoaded()) VisUI.load();
        stage = new Stage();
        label1 = Pools.obtain(VisLabel.class);
        label2 = Pools.obtain(VisLabel.class);
        label1.getStyle().fontColor = Color.WHITE;
        label1.setText("Test Label 1");
        label2.getStyle().fontColor = Color.WHITE;
        label2.setText("Test Label 2");
        label1.setPosition(200, 200);
        label2.setPosition(200, 300);
        stage.addActor(label1);
        stage.addActor(label2);
    }

    public void render(){
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.act();
        stage.draw();
    }

    public void dispose(){
        Pools.free(label1);
        Pools.free(label2);
    }
}
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Re: ReflectionPool - static reference loss on Android?

Postby tomski » Wed Apr 17, 2019 1:54 pm

This is not pure LibGDX, and you havent shown your drawables. The fact that the pools themselves are static is not why your references are broken. Calling obtain will return you any past instances that are in the pools, its up to you to manage their state properly. If you are doing something hacky, which is what it sounds like (again cant say because you have provided no code to show these objects without some external library), then its up to you to manage the state of these objects, not the pools.

Textures reinitialize themselves just fine, its most likely because you have a static Texture somewhere, and that reference is being corrupted. This is not the Pools static reference.
tomski
 
Posts: 897
Joined: Wed Jun 26, 2013 6:06 pm

Re: ReflectionPool - static reference loss on Android?

Postby graham01 » Wed Apr 17, 2019 2:06 pm

Maybe I misunderstand, but would it not be proper lifecycle management if things like pooled objects were cleared during app restart? I mean everything else gets reinitialized. It's not like Drawables/Textures are the issue, they are just obvious visual proof. Any reference in any object that is put in these pools will be broken, wont it? I apologize if I am wrong about this.

I used VisUI just to keep the test simple, otherwise I need to create a BitmapFont and LabelStyle, and Label has no default constructor so I would need a wrapper for it. Maybe that is just the problem then, in order to have a default constructor I need to get references statically. VisUI must also does this, hence the issue is also present there.
graham01
 
Posts: 204
Joined: Thu Jul 09, 2015 4:53 am

Next

Return to Libgdx

Who is online

Users browsing this forum: Google [Bot] and 1 guest