firebase-android-sdk icon indicating copy to clipboard operation
firebase-android-sdk copied to clipboard

Crashlytics OOM Crash — OutOfMemoryError in JsonWriter During Fatal Crash Serialization (No Callback Available to Trim Log for fatal crash)

Open AkashVyasCygnet opened this issue 1 week ago • 1 comments

Summary

Our Flutter application experiences a fatal crash inside Crashlytics itself. Crashlytics fails to serialize the crash event due to an OutOfMemoryError in the JSON encoder.

Because serialization fails:

  • Crashlytics never uploads such a crash due to which this crash is arise
  • The original crash cause is lost
  • The app experiences a second fatal crash caused by Crashlytics
  • Flutter cannot intercept or trim logs because no callbacks exist for fatal crashes

This makes the issue impossible to work around from the application side.

Stacktrace

Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 9232 byte allocation with 537312 free bytes and 524KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC. at java.util.Arrays.copyOf(Arrays.java:3785) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:182) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:758) at java.lang.StringBuffer.append(StringBuffer.java:431) at java.io.StringWriter.write(StringWriter.java:77) at android.util.JsonWriter.string(JsonWriter.java:453) at android.util.JsonWriter.value(JsonWriter.java:305) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:170) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:33) at com.google.firebase.encoders.json.JsonDataEncoderBuilder.lambda$static$1(JsonDataEncoderBuilder.java:63) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$$ExternalSyntheticLambda1.encode(D8$$SyntheticClass) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:314) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.internalAddIgnoreNullValues(JsonValueObjectEncoderContext.java:384) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:69) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:110) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventLogEncoder.encode(AutoCrashlyticsReportEncoder.java:588) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventLogEncoder.encode(AutoCrashlyticsReportEncoder.java:580) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.doEncode(JsonValueObjectEncoderContext.java:334) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:309) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.internalAddIgnoreNullValues(JsonValueObjectEncoderContext.java:384) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:69) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:110) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventEncoder.encode(AutoCrashlyticsReportEncoder.java:299) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventEncoder.encode(AutoCrashlyticsReportEncoder.java:277) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.doEncode(JsonValueObjectEncoderContext.java:334) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:309) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$1.encode(JsonDataEncoderBuilder.java:121) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$1.encode(JsonDataEncoderBuilder.java:129) at com.google.firebase.crashlytics.internal.model.serialization.CrashlyticsReportJsonTransform.eventToJson(CrashlyticsReportJsonTransform.java:48) at com.google.firebase.crashlytics.internal.persistence.CrashlyticsReportPersistence.persistEvent(CrashlyticsReportPersistence.java:137) at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator.lambda$persistEvent$0$com-google-firebase-crashlytics-internal-common-SessionReportingCoordinator(SessionReportingCoordinator.java:352) at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator$$ExternalSyntheticLambda0.run(D8$$SyntheticClass) at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker.lambda$submit$1(CrashlyticsWorker.java:96) at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker$$ExternalSyntheticLambda0.then(D8$$SyntheticClass) at com.google.android.gms.tasks.zze.run(com.google.android.gms:play-services-tasks@@18.1.0:1) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651) at com.google.firebase.concurrent.CustomThreadFactory.lambda$newThread$0$com-google-firebase-concurrent-CustomThreadFactory(CustomThreadFactory.java:47) at com.google.firebase.concurrent.CustomThreadFactory$$ExternalSyntheticLambda0.run(D8$$SyntheticClass) at java.lang.Thread.run(Thread.java:1119)

This shows the crash occurs entirely inside Crashlytics while constructing the JSON crash report.

Environment

Flutter Version: (your version used) Android OS: devices with 2–4GB RAM affected. App Type: Real-time CCTV app displaying a new image every second (high memory churn).

FlutterFire Libraries

firebase_analytics: 11.4.4
firebase_core: 3.12.1
firebase_crashlytics: 4.3.1

Crashlytics Android SDK version is auto-managed by FlutterFire.

Behavior Observed

  • A fatal crash happens in the app.
  • Crashlytics attempts to persist the crash event.
  • The JSON encoder (JsonWriter) allocates a very large StringWriter buffer.
  • The allocation fails → OutOfMemoryError.
  • Crashlytics itself crashes the app again.
  • Crash is never uploaded to Firebase.
  • didCrashOnPreviousExecution() remains false because persistence never finished.
  • Flutter receives no callback, no event, no logs.

This makes it impossible for us to detect, trim, or reduce the crash report.

Why This is a Crashlytics Library Issue

  • Crash is happening inside Crashlytics persistence layer
  • Developers have no API to intercept, trim, or limit event size
  • Crashlytics does not cap JSON event serialization memory
  • Crashlytics should never crash the app while trying to log a crash

Targeted Platforms

  • Android

AkashVyasCygnet avatar Dec 09 '25 05:12 AkashVyasCygnet

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Dec 09 '25 05:12 google-oss-bot

Hi @AkashVyasCygnet, thank you for raising the issue. Based on the version you shared, it looks like you're using a year old version.

Could you try using the latest Firebase SDK version and see if the issue persists?

We usually suggests to always use the latest Firebase SDK version to ensure that you have the latest updates and bug fixes that might have been already resolved.

lehcar09 avatar Dec 10 '25 16:12 lehcar09

Hey @AkashVyasCygnet. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Dec 16 '25 18:12 google-oss-bot