Memory Limiter for Android
Learn how to detect process deaths caused by Android's Memory Limiter with the Sentry Android SDK.
Experimental
The Memory Limiter integration is experimental. It's available in Sentry Android SDK version ≥ 8.57.0, and Android API level ≥ 37.
Android 17 introduced the Memory Limiter, a system service available on supported devices that's responsible for managing per-app memory budgets and slowing down or terminating apps that exceed them. Terminations don't produce a Java exception or a stack trace, which makes them easy to miss if you're only looking for traditional crashes.
Sentry's Memory Limiter integration generates fatal Sentry events for Memory Limiter terminations by scanning ApplicationExitInfo records written by the Android OS.
To learn more about Memory Limiter, see Google's documentation and the Android Developers Blog.
- You're using Sentry Android SDK version
8.57.0or later. - The device is running Android 17 (API level 37) or later.
- The SDK has a cache directory available.
- You enable the integration explicitly. (It's disabled by default.)
You can enable the integration in your AndroidManifest.xml:
AndroidManifest.xml<application>
<meta-data
android:name="io.sentry.memory-limiter.enable"
android:value="true"
/>
</application>
<application>
<meta-data
android:name="io.sentry.memory-limiter.enable"
android:value="true"
/>
</application>
Or when you initialize the SDK:
SentryAndroid.init(this) { options ->
options.isMemoryLimiterEnabled = true
}
SentryAndroid.init(this) { options ->
options.isMemoryLimiterEnabled = true
}
SentryAndroid.init(this, options -> {
options.setMemoryLimiterEnabled(true);
});
When the Memory Limiter terminates a process, info about that process is recorded by the Android OS in the form of an ApplicationExitInfo entry, tracked by the ActivityManager system service.
On the next app start, the SDK searches all exit info records for Memory Limiter deaths. If it finds a match, the SDK creates a synthetic fatal event with the MemoryLimitExceeded exception type. For the latest matching exit, the SDK also backfills persisted context from the previous process when that data is available.
By default, the SDK reports only the latest matching Memory Limiter exit. If you also want older retained exits from the same Android history, enable historical reporting:
AndroidManifest.xml<application>
<meta-data
android:name="io.sentry.memory-limiter.enable"
android:value="true"
/>
<meta-data
android:name="io.sentry.memory-limiter.report-historical"
android:value="true"
/>
</application>
<application>
<meta-data
android:name="io.sentry.memory-limiter.enable"
android:value="true"
/>
<meta-data
android:name="io.sentry.memory-limiter.report-historical"
android:value="true"
/>
</application>
SentryAndroid.init(this) { options ->
options.isMemoryLimiterEnabled = true
options.isReportHistoricalMemoryLimiterExits = true
}
SentryAndroid.init(this, options -> {
options.setMemoryLimiterEnabled(true);
options.setReportHistoricalMemoryLimiterExits(true);
});
Historical exits are lighter-weight reports. Unlike the latest retained exit, they aren't enriched with persisted Sentry context from the previous process.
Memory Limiter reports appear as fatal events with:
- Exception type
MemoryLimitExceeded - Mechanism type
AppExitInfofor the latest exit, orHistoricalAppExitInfofor older retained exits - The original Android exit description stored on the event's
mechanism - Memory Limiter-specific mechanism data such as
memory_limit_classandprocess_importance
The memory_limit_class value is a best-effort classification derived from process_importance and the table shown here. It consists of three buckets:
visiblenot_visiblecached
These fields can help you approximate the memory capacity allocated to your process before it was killed and whether it was visible to users.
Values for process_importance are taken from ApplicationExitInfo.importance. Memory Limiter events are grouped by process_importance in Sentry's issues feed:
If you're using Release Health, the latest recovered Memory Limiter exit also marks the previous session as abnormal on the next app launch.
That keeps release health closer to what users experienced instead of treating the terminated session as a healthy exit.
For more about session states, see Session Status.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").