rive-app/rive-ios

Rive memory is not cleared

Closed this issue ยท 4 comments

somero commented

Description

I've noticed that after showing a rive animation, and then removing it from the view, the memory usage does not go back to how it was before showing the animation.
Is this on purpose? Can we turn it off somehow?

This is the memory usage of the repro app:
image
After the first 5 seconds with only text in view, we add the rive animation for 5 seconds and remove it.

Provide a Repro

struct ContentView: View {
    @State var showRive = false
    @State var riveShown = false
    var body: some View {
        if showRive {
            VStack {
                RiveViewModel(fileName: "juggling", stateMachineName: "State Machine 1").view()
                Text("Loading...")
            }
            .onAppear {
                Task {
                    try? await Task.sleep(for: Duration .seconds(5))
                    self.showRive = false
                    self.riveShown = true
                }
            }
        } else {
            Text("Loaded successfully!")
                .onAppear {
                    Task {
                        try? await Task.sleep(for: Duration .seconds(5))
                        if !riveShown {
                            self.showRive = true
                        }
                    }
                }
        }
    }
}

Source .riv/.rev file

juggling.zip

Expected behavior

After the animation view is cleared from view, the memory level should be back to how it was before. If this is caching optimization, we'd like to have the option to disable it for animations that are not reused.

Device & Versions (please complete the following information)

  • Device: iPhone 13 mini
  • iOS version: 16.3.1

Hi @somero thank you for reporting this, we are having a look into it. We are able to reproduce a leak and are looking to get a patch out for that shortly.

Hi @somero, we've just published an updated release that addresses some of the issues you are seeing so please give 3.1.11 a go.

As part of this we have fixed a couple of memory leaks.

But critically to the issue you are reporting but we have also changed how we use skia graphics contexts. We use Skia as our renderer & it has a a graphics context that can cache some rendered outputs. Previously we would simply let this be managed entirely by Skia, but we now clear the context when no more RiveViews are in memory.

There is still some overhead to using Skia that we cannot mitigate, and so you will see an additional memory footprint after closing a riveView. This footprint will be more limited, and & will not grow significantly with every additional RiveFile. different animations may require Skia to compile different shaders though so there can be a few jumps based on what is being displayed.

If you load rive files from the web by passing urls to our RiveViews, NSURLSession requests also have a longer term impact on memory usage. Https requests have a much higher footprint here as certificate chains are stored. This is also a one time cost, and it appears to depend on where you load the data from.

somero commented

Great! Thanks for the fix, and also for the detailed explanation. Highly appreciated ๐Ÿ™
I'll test it out as soon as I can

Closing this for now, it appears to have fixed memory issues for others that have experiences this