feat(android): Parse memory and GC info from ANR thread dumps#5428
feat(android): Parse memory and GC info from ANR thread dumps#5428markushi wants to merge 8 commits into
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
📲 Install BuildsAndroid
|
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 8558cac | 306.16 ms | 355.24 ms | 49.09 ms |
| 8687935 | 332.52 ms | 362.23 ms | 29.71 ms |
| 9054d65 | 330.94 ms | 403.24 ms | 72.30 ms |
| fc5ccaf | 322.49 ms | 405.25 ms | 82.76 ms |
| 8c1fb22 | 316.62 ms | 352.78 ms | 36.16 ms |
| d8912da | 329.94 ms | 389.68 ms | 59.74 ms |
| d15471f | 315.61 ms | 360.22 ms | 44.61 ms |
| b6702b0 | 395.86 ms | 409.98 ms | 14.12 ms |
| 62b579c | 318.48 ms | 367.71 ms | 49.24 ms |
| ed33deb | 312.34 ms | 369.71 ms | 57.37 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 8558cac | 0 B | 0 B | 0 B |
| 8687935 | 1.58 MiB | 2.19 MiB | 619.17 KiB |
| 9054d65 | 1.58 MiB | 2.29 MiB | 723.38 KiB |
| fc5ccaf | 1.58 MiB | 2.13 MiB | 557.54 KiB |
| 8c1fb22 | 0 B | 0 B | 0 B |
| d8912da | 0 B | 0 B | 0 B |
| d15471f | 1.58 MiB | 2.13 MiB | 559.54 KiB |
| b6702b0 | 1.58 MiB | 2.12 MiB | 551.79 KiB |
| 62b579c | 0 B | 0 B | 0 B |
| ed33deb | 1.58 MiB | 2.13 MiB | 559.52 KiB |
Previous results on branch: feat/anr-thread-dump-memory-info
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 976a904 | 315.40 ms | 352.60 ms | 37.20 ms |
| e24f273 | 348.98 ms | 407.75 ms | 58.77 ms |
| fc3a862 | 316.67 ms | 394.40 ms | 77.73 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 976a904 | 0 B | 0 B | 0 B |
| e24f273 | 0 B | 0 B | 0 B |
| fc3a862 | 0 B | 0 B | 0 B |
|
@sentry review |
0xadam-brown
left a comment
There was a problem hiding this comment.
Really nice. Just a few comments; none have to block us.
| "free_memory_until_oome": 196083712, | ||
| "total_memory": 7774208, | ||
| "max_memory": 201326592 | ||
| } |
There was a problem hiding this comment.
Could be nice to test the preservation of fields in the unknown map as well. (Up to you.)
| private static final long MB = 1024 * KB; | ||
| private static final long GB = 1024 * MB; | ||
|
|
||
| private static final String FREE_MEMORY_PREFIX = "Free memory "; |
There was a problem hiding this comment.
Do we have a sense for how frequently these strings change, and how stable they are across OEMs? Just wondering how much we need to monitor the presence of unparseable / null values here vs our ability to set it and forget it.
(Doesn't have to hold up this PR, regardless.)
There was a problem hiding this comment.
Yeah, that's some good input! I'm not aware of any "flavors" across vendors. It's probably most practicable to have a look at some customer data as soon as the feature rolls out.
| * and may be null on other platforms. | ||
| */ | ||
| public final class ArtContext implements JsonUnknown, JsonSerializable { | ||
| public static final String TYPE = "art"; |
There was a problem hiding this comment.
Newbie question: Would "runtime" make more sense as the type, with other platforms supplying their own *Context type? (or "runtime.art" if our conventions permit multipart keys)
"runtime" seems a better match for the abstraction level of things like "gpu" and "device", but perhaps Relay doesn't permit that sort of key-value "polymorphism" (ie, single key but different value types based on the platform).
There was a problem hiding this comment.
@0xadam-brown we do allow multipart keys and we generally should try to follow/extend OTEL conventions (if it fits) and only add our own stuff if there really is no equivalent (this hasn't always been the case but recently we decided to do enforce this).
In this case I suggest we do art.gc.xyz and art.memory.xyz. OTEL defines a generic process.runtime.name/version/description attribute but for runtime specifics they favour namespacing it under the runtime directly e.g
dotnet.gc.*, jvm.gc.* (we already do this for JVM)
There was a problem hiding this comment.
Use dotted attribute names (e.g. gc.total_count, memory.free) to match the sentry-conventions schema from getsentry/sentry-conventions#382. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📜 Description
Parses memory and GC metrics from ANRv2 dumps (ApplicationExitInfo traces) and attaches them as a new
artcontext on ANR events.New classes:
ArtContext— serializable context for ART runtime memory/GC fields (bytes and milliseconds), added toContextsArtContextParser— parses lines likeFree memory 3107KB,Total GC time: 11.807msusing simple suffix-based parsing (counterpart to Android'sPrettySizeandPrettyDurationoutput)The parsed data is attached as
event.contexts.artwith attribute names aligned to sentry-conventions#382.Resolves: #2801
💡 Motivation and Context
ANR thread dumps from ART contain memory and GC statistics that are currently ignored. This information is valuable for diagnosing memory pressure-related ANRs.
💚 How did you test it?
📝 Checklist
sendDefaultPIIis enabled.