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

Memory leak in the SpeedTest example (Skia.Color) #2992

Open
1 task
gwesseling opened this issue Mar 3, 2025 · 4 comments
Open
1 task

Memory leak in the SpeedTest example (Skia.Color) #2992

gwesseling opened this issue Mar 3, 2025 · 4 comments
Labels
bug Something isn't working

Comments

@gwesseling
Copy link

gwesseling commented Mar 3, 2025

Description

We are encountering a memory leak caused by using Skia.Color. We are using a similar implementation to what is used in SpeedTest example. I have also run the speedTest example directly in our app, which gives the same result. I could unfortunately not run the speedTest example in the Skia repo to confirm it is something in our setup.

It seems to be related to this line, we found this in our implementation and the SpeedTest example:
https://github.com/Shopify/react-native-skia/blob/main/apps/paper/src/Examples/SpeedTest/SpeedTest.tsx#L299

When running the instruments tool for leaks on a release build we see the following:

Image

Image

If we don't animate the color and make it a Skia.Color defined outside our component everything seems to be fine.

React Native Skia Version

1.11.7

React Native Version

0.76.3

Using New Architecture

  • Enabled

Steps to Reproduce

In our case we are animating the color of the paragraph.

  const paragraph = useDerivedValue(() => {
    // Are the font loaded already?
    if (!customFontMgr) {
      return null;
    }

    const paragraphStyle = {
      textAlign: props.textAlign || TextAlign.Left,
    };

    const textStyle = {
      color: Skia.Color(preColor.value),
      fontFamilies: [fontWeight],
      fontSize: props.fontSize,
    };

    return Skia.ParagraphBuilder.Make(paragraphStyle, customFontMgr)
      .pushStyle(textStyle)
      .addText(preText.value;)
      .pop()
      .build();
  });

Snack, Code Example, Screenshot, or Link to Repository

https://github.com/Shopify/react-native-skia/blob/main/apps/paper/src/Examples/SpeedTest/SpeedTest.tsx

@gwesseling gwesseling added the bug Something isn't working label Mar 3, 2025
@gwesseling gwesseling changed the title Memory leak in the SpeedTest example regarding Skia.Color Memory leak in the SpeedTest example (Skia.Color) Mar 3, 2025
@gwesseling
Copy link
Author

We are also seeing something similar using a path effect (DashPathEffect). But I need to look more into that, since we are not animating it, we are only animating the group around it.

Image
Image

@wcandillon
Copy link
Contributor

is this related to facebook/hermes#982? The object is not leaking but it is seen so lightweight by the gc that it doesn't garbage collect it? Does using .dispose() on the color using the same color instance fixes the issue?

@gwesseling
Copy link
Author

gwesseling commented Mar 3, 2025

Thanks for your quick reaction @wcandillon 🙌.

The things you are pointing out make a lot of sense, especially after reading PRs like #1600. I will check the .dispose() function soon on the color instance to see if this fixes the issue and report back.

@gwesseling
Copy link
Author

gwesseling commented Mar 3, 2025

I have tried running the dispose() function on the SkParagraphBuilder, but that does not make a difference for the color instance. It still appears in the instruments. The Skia.Color does not have a function like this? it only returns a Float32Array, unless I am missing something here.

However, I might have found a way to limit the amount of time the color instance gets created on our side. This would already be a big improvement, but still, we are animating the color using reanimated's withTiming. That would still mean a lot of instances get created when animating the color :/

We are currently getting to the point where the os watchdog is terminating our app to free up memory. Our app is intended to run on a tablet 24/7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants