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: Profiling memory leaks #3055

Merged
merged 5 commits into from
May 24, 2023
Merged

fix: Profiling memory leaks #3055

merged 5 commits into from
May 24, 2023

Conversation

indragiek
Copy link
Member

📜 Description

This fixes most of the memory leaks reported in #2980. I checked before/after the fixes using Instruments.

Before:
CleanShot 2023-05-23 at 23 33 23@2x

After:
CleanShot 2023-05-23 at 23 33 28@2x

There is 1 memory leak left to fix that I couldn't find a solution for yet, but the other leaks are fixed.

The root of the problem seems to be that std::thread does not correctly deallocate parameters that are passed to the newly spawned thread. It's unclear if this is expected behavior or not, but the fix was simple: pass parameters that were being copied (and leaked) by reference.

There's also one more unrelated fix to a crash that I found while debugging the leaks - it turns out -[NSString stringWithUTF8String:] can return nil for malformed data and we weren't checking for nil.

💚 How did you test it?

Check before/after the fix in Instruments, run all existing unit tests.

📝 Checklist

You have to check all boxes before merging:

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

indragiek added 3 commits May 23, 2023 22:21
Passing the std::function (which captures the `SentryProfilingState`) to the thread constructor creates a copy of the std::function that appears to not be destructed when the thread exits - unclear if this is expected behavior, but passing it as a const ref instead of a copy fixes the leak.
This is the same fix as the other leak fix, for the same reason - std::thread leaks the parameters even after the thread exits
};
NSString *const labelNSStr =
[NSString stringWithUTF8String:backtrace.queueMetadata.label->c_str()];
// -[NSString stringWithUTF8String:] can return `nil` for malformed string data
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a repro of this happening:
CleanShot 2023-05-23 at 22 48 47@2x

@codecov
Copy link

codecov bot commented May 24, 2023

Codecov Report

Merging #3055 (da70c38) into main (4053ee9) will increase coverage by 0.021%.
The diff coverage is 100.000%.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #3055       +/-   ##
=============================================
+ Coverage   88.844%   88.865%   +0.021%     
=============================================
  Files          492       492               
  Lines        52976     53017       +41     
  Branches     18970     18992       +22     
=============================================
+ Hits         47066     47114       +48     
+ Misses        4953      4948        -5     
+ Partials       957       955        -2     
Impacted Files Coverage Δ
Sources/Sentry/SentryProfiler.mm 85.594% <100.000%> (+0.060%) ⬆️
Sources/Sentry/SentrySamplingProfiler.cpp 81.443% <100.000%> (ø)

... and 10 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4053ee9...da70c38. Read the comment docs.

@github-actions
Copy link

github-actions bot commented May 24, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1229.80 ms 1251.65 ms 21.86 ms
Size 20.76 KiB 435.06 KiB 414.30 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
2af280d 1219.33 ms 1239.98 ms 20.65 ms
1bbcb9c 1189.61 ms 1223.50 ms 33.89 ms
1db04d8 1250.20 ms 1258.12 ms 7.92 ms
0001a09 1223.90 ms 1249.56 ms 25.66 ms
8526e93 1228.24 ms 1239.14 ms 10.90 ms
c0b4b71 1218.16 ms 1251.28 ms 33.12 ms
8f397a7 1196.55 ms 1226.82 ms 30.27 ms
bd2afa6 1192.31 ms 1210.37 ms 18.05 ms
ecd9ecd 1191.76 ms 1216.92 ms 25.16 ms
1bf8571 1215.31 ms 1232.48 ms 17.17 ms

App size

Revision Plain With Sentry Diff
2af280d 20.76 KiB 435.22 KiB 414.46 KiB
1bbcb9c 20.76 KiB 426.10 KiB 405.34 KiB
1db04d8 20.76 KiB 435.50 KiB 414.74 KiB
0001a09 20.76 KiB 433.19 KiB 412.43 KiB
8526e93 20.76 KiB 420.22 KiB 399.47 KiB
c0b4b71 20.76 KiB 430.98 KiB 410.22 KiB
8f397a7 20.76 KiB 420.55 KiB 399.79 KiB
bd2afa6 20.76 KiB 420.55 KiB 399.79 KiB
ecd9ecd 20.76 KiB 420.23 KiB 399.47 KiB
1bf8571 20.76 KiB 437.12 KiB 416.36 KiB

Previous results on branch: indragiek/fix-leaks

Startup times

Revision Plain With Sentry Diff
7120167 1216.18 ms 1267.50 ms 51.32 ms

App size

Revision Plain With Sentry Diff
7120167 20.76 KiB 435.06 KiB 414.30 KiB

Copy link
Contributor

@brustolin brustolin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @indragiek. LGTM.

Copy link
Member

@armcknight armcknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks @indragie

@@ -107,8 +107,8 @@ namespace profiling {
}
isSampling_ = true;
numSamples_ = 0;
thread_ = std::thread(samplingThreadMain, port_, clock_, delaySpec_, cache_, callback_,
std::ref(numSamples_), onThreadStart);
thread_ = std::thread(samplingThreadMain, port_, clock_, delaySpec_, std::cref(cache_),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL std::ref and std::cref, nice! I was trying to do this with & which wouldn't compile 😭

@indragiek indragiek merged commit 98752f3 into main May 24, 2023
@indragiek indragiek deleted the indragiek/fix-leaks branch May 24, 2023 16:19
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.

5 participants