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

Fix memory leak issue in SentryFlutterPlugin #1588

Merged
merged 6 commits into from
Aug 9, 2023

Conversation

linkaipeng
Copy link
Contributor

I fixed the memory leak issue in SentryFlutterPlugin by removing the anonymous inner class that was holding a reference to the external SentryFlutterPlugin object, which was causing a memory leak problem with the MethodChannel object.

📜 Description

💡 Motivation and Context

To reproduce the steps:

  • Integrate sentry_flutter into your project.
  • Open the application's MainActivity and press the back button to return to the Launcher. Repeat this process multiple times.
  • Use Android Studio Profiler to dump the memory for analysis.

WX20230808-095220

💚 How did you test it?

Since the SentryFlutterPlugin does not have unit test code, I repeated the steps mentioned above after making the modifications and confirmed that the issue has been fixed.

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPii is enabled
  • I updated the docs if needed
  • All tests passing
  • No breaking changes

🔮 Next steps

I fixed the memory leak issue in SentryFlutterPlugin by removing the anonymous inner class that was holding a reference to the external SentryFlutterPlugin object, which was causing a memory leak problem with the MethodChannel object.
@linkaipeng linkaipeng changed the title Fixing memory leak issue in SentryFlutterPlugin Fix memory leak issue in SentryFlutterPlugin Aug 8, 2023
@marandaneto
Copy link
Contributor

Since the SentryFlutterPlugin does not have unit test code

We are currently adding tests #1587

@marandaneto
Copy link
Contributor

@linkaipeng thanks for the PR.

I'm not sure the suggested changes will have any effect, the leak seems to be in https://github.com/getsentry/sentry-java/blob/549cbb4657b9dea1048c4882e79504e87d6acc4f/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java#L26 (based on the SS)

The changes with the beforeSend callback are not holding any reference, just modifying the metadata.

Can you elaborate on what exactly is causing this, which line, etc?

@romtsn or @markushi can chime in as well since they own this part of the code.

@romtsn
Copy link
Member

romtsn commented Aug 8, 2023

What is LocalizationPlugin? Is this something from Flutter/Dart or custom?

@romtsn
Copy link
Member

romtsn commented Aug 8, 2023

Hm, found this, looks very similar ryanheise/audio_session#12. Should we nullify the channel in onDetachedFromEngine? This was the fix from that repo ryanheise/audio_session@f9f114a

@linkaipeng
Copy link
Contributor Author

@linkaipeng thanks for the PR.

I'm not sure the suggested changes will have any effect, the leak seems to be in https://github.com/getsentry/sentry-java/blob/549cbb4657b9dea1048c4882e79504e87d6acc4f/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java#L26 (based on the SS)

The changes with the beforeSend callback are not holding any reference, just modifying the metadata.

Can you elaborate on what exactly is causing this, which line, etc?

@romtsn or @markushi can chime in as well since they own this part of the code.

@marandaneto Thank you for your reply. The reason is that the BeforeSendCallback instance passed to beforeSend is an anonymous inner class, and through the bytecode, it is clear that it holds a reference to the SentryFlutterPlugin object, which is the root cause of the leak.

The approach I took was to completely decouple the BeforeSendCallback instance from SentryFlutterPlugin and remove its reference to the SentryFlutterPlugin object.

Before modification:
image

After modification:

image

Another way to modify is to make the channel nullable and set it to null in the onDetachedFromEngine method. However, in my understanding, the purpose of BeforeSendCallback is to modify the metadata of the SentryEvent Methods like setEventOriginTag and addPackages seem more like utility methods and should not belong to the SentryFlutterPlugin. Therefore, changing them to static methods would be more appropriate.

@marandaneto
Copy link
Contributor

Oh I see, that makes sense @linkaipeng thanks for the explanation.
There are probably some linting issues, I will run CI, also please add a new entry to the changelog.

@codecov
Copy link

codecov bot commented Aug 8, 2023

Codecov Report

Patch coverage has no change and project coverage change: +0.23% 🎉

Comparison is base (07d9b4d) 88.44% compared to head (896dad3) 88.68%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1588      +/-   ##
==========================================
+ Coverage   88.44%   88.68%   +0.23%     
==========================================
  Files         132      124       -8     
  Lines        4274     3940     -334     
==========================================
- Hits         3780     3494     -286     
+ Misses        494      446      -48     

see 8 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@linkaipeng
Copy link
Contributor Author

Oh I see, that makes sense @linkaipeng thanks for the explanation. There are probably some linting issues, I will run CI, also please add a new entry to the changelog.

Thank you. The changelog has been committed.

@marandaneto
Copy link
Contributor

Oh I see, that makes sense @linkaipeng thanks for the explanation. There are probably some linting issues, I will run CI, also please add a new entry to the changelog.

Thank you. The changelog has been committed.

the lining issues:

ktlint version: 0.50.0
reviewdog: This GitHub token doesn't have write permission of Review API [1],
so reviewdog will report results via logging command [2] and create annotations similar to
github-pr-check reporter as a fallback.
[1]: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target,
[2]: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions#logging-commands
reviewdog: input data has violations
Error: [ktlint] reported by reviewdog 🐶
Unnecessary trailing comma before ")"

Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:211:37: error: Unnecessary trailing comma before ")" (standard:trailing-comma-on-call-site)
Error: [ktlint] reported by reviewdog 🐶
Unnecessary trailing comma before ")"

Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:252:33: error: Unnecessary trailing comma before ")" (standard:trailing-comma-on-call-site)
Error: [ktlint] reported by reviewdog 🐶
Exceeded max line length (100)

Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:403:1: error: Exceeded max line length (100) (standard:max-line-length)
Error: [ktlint] reported by reviewdog 🐶
Exceeded max line length (100)

Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:427:1: error: Exceeded max line length (100) (standard:max-line-length)

Fix some lining issues for SentryFlutterPlugin.
@linkaipeng
Copy link
Contributor Author

Oh I see, that makes sense @linkaipeng thanks for the explanation. There are probably some linting issues, I will run CI, also please add a new entry to the changelog.

Thank you. The changelog has been committed.

the lining issues:

ktlint version: 0.50.0
reviewdog: This GitHub token doesn't have write permission of Review API [1],
so reviewdog will report results via logging command [2] and create annotations similar to
github-pr-check reporter as a fallback.
[1]: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target,
[2]: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions#logging-commands
reviewdog: input data has violations
Error: [ktlint] reported by reviewdog 🐶
Unnecessary trailing comma before ")"
Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:211:37: error: Unnecessary trailing comma before ")" (standard:trailing-comma-on-call-site)
Error: [ktlint] reported by reviewdog 🐶
Unnecessary trailing comma before ")"
Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:252:33: error: Unnecessary trailing comma before ")" (standard:trailing-comma-on-call-site)
Error: [ktlint] reported by reviewdog 🐶
Exceeded max line length (100)
Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:403:1: error: Exceeded max line length (100) (standard:max-line-length)
Error: [ktlint] reported by reviewdog 🐶
Exceeded max line length (100)
Raw Output:
flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt:427:1: error: Exceeded max line length (100) (standard:max-line-length)

Fixed.

CHANGELOG.md Outdated Show resolved Hide resolved
@marandaneto marandaneto enabled auto-merge (squash) August 9, 2023 08:43
@marandaneto marandaneto merged commit adf71f4 into getsentry:main Aug 9, 2023
76 of 79 checks passed
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

Successfully merging this pull request may close these issues.

3 participants