EsotericSoftware / spine-runtimes

2D skeletal animation runtimes for Spine.
http://esotericsoftware.com/
Other
4.43k stars 2.92k forks source link

[Android]SpineView leaks #2682

Closed Yetland closed 2 weeks ago

Yetland commented 2 weeks ago

SpineView leaks image

Yetland commented 2 weeks ago

https://github.com/user-attachments/assets/a0fb3d7f-dcfe-47cb-9884-c23e6412a195

badlogic commented 2 weeks ago

What tool is that? It's not immediately clear to me why SpineView would continue to live while holding on to its context which was supposedly destroyed as per the tools output. Hm, maybe it is being retained by the choreographer, as it registers a callback to update itself periodically.

Yetland commented 2 weeks ago

What tool is that? It's not immediately clear to me why SpineView would continue to live while holding on to its context which was supposedly destroyed as per the tools output. Hm, maybe it is being retained by the choreographer, as it registers a callback to update itself periodically.

I used LeakCanary as the memory leak detection tool. I cloned the code locally without making any changes. Then I ran the app and exited, and LeakCanary automatically detected the memory leak and generated a report. The report shows that there is a memory leak issue. How should this issue be fixed?

badlogic commented 2 weeks ago

Well, I have to fix it by first identifying why the leak occurs, then modifying the code for that to not happen :)

I tried to reproduce this with the examples Android app in spine-android. I added:

debugImplementation("com.squareup.leakcanary:leakcanary-android:2.14")

To the example projects dependencies. I then run the example on the emulator through Android Studio. LogCat shows that Leakcanary is starting up. I open and close all activities in the example. Leakcanary doesn't detect any leaks.

I also went through the SpineView sources to check if there's any obvious leak, i.e. through callbacks to Choreographer. There are not. We use Choreographer.postFrameCallback(SpineView.this) which only holds on to the SpineView (and transitively to the activity context) until the next frame has been rendered. There are no other obvious ways for SpineView and its transitive dependencies to leak.

So, I can not reproduce this. Can you provide steps to reproduce this? I'll re-open if I can repro.

Yetland commented 2 weeks ago

I have created a sample project LeaksExample that you can clone and run. Follow this sequence of steps: Open the app -> Click [Navigate to MainActivity] -> Spine Android Examples Page -> Click [Simple Animation] -> Back -> Spine Android Examples Page -> Click [Play/Pause] -> Click back to close app -> Open the app . Then wait for the Leaks detection(about 30 seconds).