[Help Wanted]: `OutOfMemoryError`s and crashes occurring on some devices
Required Reading
- [x] Confirmed
Plugin Version
4.16.9
Mobile operating-system(s)
- [ ] iOS
- [x] Android
Device Manufacturer(s) and Model(s)
Samsung Galaxy A54 5G, Samsung Galaxy Tab A7 Lite, Samsung Galaxy M32 5G, Samsung Galaxy A32
Device operating-systems(s)
Android 13, 14
What do you require assistance about?
In the Google Play Console, some devices occassionally encounter java.lang.OutOfMemoryErrors, or crash with some native (segmentation fault-like) error. I'm unsure if this is even something that could be prevented by my own app or this package, hence a Help Wanted request and not a Bug report.
From the Google Play Console, I have the following devices:
- Samsung Galaxy A54 5G @ Android 14:
OutOfMemoryError - Samsung Galaxy Tab A7 Lite LTE @ Android 14:
OutOfMemoryError - Samsung Galaxy M32 5G @ Android 13: native crash
- Samsung Galaxy A32 @ Android 13: native crash
Are there any likely causes or possibilities to track down these issues? Unfortunately, these devices are our customers', so I'm unable to see or test them for myself. But maybe seeing the files in this package in the stack traces can help you point out where the issue originates from...
[Optional] Plugin Code and/or Config
bg.Config(
debug: false,
logLevel: bg.Config.LOG_LEVEL_INFO,
stopOnTerminate: false,
startOnBoot: false,
batchSync: true,
// With a location every 3 seconds,
// this is expected to take about 4 minutes
autoSync: true,
autoSyncThreshold: 75,
httpRootProperty: 'locations',
maxDaysToPersist: 7,
logMaxDays: 1,
// When the apparent movement speed was over 144 km/h, discard the location
speedJumpFilter: 40,
// Disable the motion API, and never automatically pause the service
disableMotionActivityUpdates: true,
disableStopDetection: true,
pausesLocationUpdatesAutomatically: false,
authorization: bg.Authorization(accessToken: accessToken),
url: endpoint,
extras: {...},
notification: ...,
backgroundPermissionRationale: ...,
)
[Optional] Relevant log output
Samsung Galaxy A54 5G @ Android 14:
Exception java.lang.OutOfMemoryError: Failed to allocate a 24 byte allocation with 53280 free bytes and 52KB until OOM, target footprint <US_SOCIAL_SECURITY_NUMBER>, growth limit <US_SOCIAL_SECURITY_NUMBER>; giving up on allocation because <1% of heap free after GC.
at java.util.HashMap.newNode (HashMap.java:1907)
at java.util.HashMap.putVal (HashMap.java:636)
at java.util.HashMap.put (HashMap.java:617)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toMap (BackgroundGeolocationModule.java:1043)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toMap (BackgroundGeolocationModule.java:1041)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toMap (BackgroundGeolocationModule.java:1041)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toList (BackgroundGeolocationModule.java:1058)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.access$300 (BackgroundGeolocationModule.java)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule$11.onSuccess (BackgroundGeolocationModule.java:578)
at com.transistorsoft.locationmanager.adapter.BackgroundGeolocation$v0$a.run (Unknown Source:8)
at android.os.Handler.handleCallback (Handler.java:958)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:230)
at android.os.Looper.loop (Looper.java:319)
at android.app.ActivityThread.main (ActivityThread.java:8919)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1103)
Exception java.lang.OutOfMemoryError:
at java.lang.StringFactory.newStringFromUtf8Bytes
at java.lang.StringFactory.newStringFromBytes (StringFactory.java:94)
at java.lang.StringFactory.newStringFromBytes (StringFactory.java:68)
at java.lang.StringFactory.newStringFromBytes (StringFactory.java:44)
at java.lang.Long.toString (Long.java:482)
at org.json.JSONObject.numberToString (JSONObject.java:760)
at org.json.JSONStringer.value (JSONStringer.java:258)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONStringer.value (JSONStringer.java:246)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONStringer.value (JSONStringer.java:246)
at org.json.JSONArray.writeTo (JSONArray.java:616)
at org.json.JSONStringer.value (JSONStringer.java:242)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONObject.toString (JSONObject.java:702)
at com.transistorsoft.locationmanager.http.HttpService.a (SourceFile:11)
at com.transistorsoft.locationmanager.http.HttpService.f (SourceFile:2)
at com.transistorsoft.locationmanager.http.HttpService.e (SourceFile:1)
at com.transistorsoft.locationmanager.http.HttpService$e.run (Unknown Source:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:644)
at java.lang.Thread.run (Thread.java:1012)
---------------------------------------------------------------------------------------------------
Samsung Galaxy Tab A7 Lite LTE @ Android 14:
Exception java.lang.OutOfMemoryError:
at java.util.LinkedHashMap.sequencedKeySet (LinkedHashMap.java:673)
at java.util.LinkedHashMap.keySet (LinkedHashMap.java:658)
at org.json.JSONObject.keys (JSONObject.java:664)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toMap (BackgroundGeolocationModule.java:1031)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toMap (BackgroundGeolocationModule.java:1041)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.toList (BackgroundGeolocationModule.java:1058)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule.access$300 (BackgroundGeolocationModule.java)
at com.transistorsoft.flutter.backgroundgeolocation.BackgroundGeolocationModule$11.onSuccess (BackgroundGeolocationModule.java:578)
at com.transistorsoft.locationmanager.adapter.BackgroundGeolocation$v0$a.run (Unknown Source:8)
at android.os.Handler.handleCallback (Handler.java:958)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:230)
at android.os.Looper.loop (Looper.java:319)
at android.app.ActivityThread.main (ActivityThread.java:8919)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1103)
Exception java.lang.OutOfMemoryError:
at java.util.Arrays.copyOf (Arrays.java:3585)
at java.lang.AbstractStringBuilder.ensureCapacityInternal (AbstractStringBuilder.java:177)
at java.lang.AbstractStringBuilder.append (AbstractStringBuilder.java:753)
at java.lang.StringBuilder.append (StringBuilder.java:257)
at org.json.JSONStringer.string (JSONStringer.java:354)
at org.json.JSONStringer.key (JSONStringer.java:386)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONStringer.value (JSONStringer.java:246)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONStringer.value (JSONStringer.java:246)
at org.json.JSONArray.writeTo (JSONArray.java:616)
at org.json.JSONStringer.value (JSONStringer.java:242)
at org.json.JSONObject.writeTo (JSONObject.java:734)
at org.json.JSONObject.toString (JSONObject.java:702)
at com.transistorsoft.locationmanager.http.HttpService.a (SourceFile:11)
at com.transistorsoft.locationmanager.http.HttpService.f (SourceFile:2)
at com.transistorsoft.locationmanager.http.HttpService.e (SourceFile:1)
at com.transistorsoft.locationmanager.http.HttpService$e.run (Unknown Source:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:644)
at java.lang.Thread.run (Thread.java:1012)
---------------------------------------------------------------------------------------------------
Samsung Galaxy M32 5G @ Android 13:
SourceFile - com.transistorsoft.locationmanager.service.AbstractService.c
#00 pc 0x00000000004fc1e0 /apex/com.android.art/lib64/libart.so (art::DumpNativeStack+108)
#01 pc 0x00000000004fe898 /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack const+376)
#02 pc 0x000000000050068c /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run+216)
#03 pc 0x000000000022c2b0 /apex/com.android.art/lib64/libart.so (art::Thread::RunCheckpointFunction+144)
#04 pc 0x0000000000993c24 /apex/com.android.art/lib64/libart.so (artTestSuspendFromCode+152)
#05 pc 0x000000000037e99c /apex/com.android.art/lib64/libart.so (art_quick_test_suspend+156)
at android.os.Parcel.nativeWriteString16 (Native method)
at android.os.Parcel.writeString16NoHelper (Parcel.java:1146)
at android.os.Parcel$ReadWriteHelper.writeString16 (Parcel.java:486)
at android.os.Parcel.writeString16 (Parcel.java:1125)
at android.os.Parcel.writeString (Parcel.java:1115)
at android.os.Parcel.writeArrayMapInternal (Parcel.java:1298)
at android.os.BaseBundle.writeToParcelInner (BaseBundle.java:1802)
at android.os.Bundle.writeToParcel (Bundle.java:1362)
at android.os.Parcel.writeBundle (Parcel.java:1368)
at android.app.Notification.writeToParcelImpl (Notification.java:3223)
at android.app.Notification.writeToParcel (Notification.java:3099)
at android.os.Parcel.writeTypedObject (Parcel.java:2191)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:6987)
at android.app.Service.startForeground (Service.java:743)
at com.transistorsoft.locationmanager.service.AbstractService.c (SourceFile:1)
at com.transistorsoft.locationmanager.service.AbstractService.a (SourceFile:8)
at com.transistorsoft.locationmanager.service.TrackingService.onStartCommand (unavailable:1)
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5243)
at android.app.ActivityThread.-$$Nest$mhandleServiceArgs (unavailable)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2447)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8762)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
---------------------------------------------------------------------------------------------------
Samsung Galaxy A32 @ Android 13:
SourceFile - com.transistorsoft.locationmanager.service.AbstractService.c
#00 pc 0x00000000006aa9a8 /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+128)
#01 pc 0x0000000000712b44 /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+236)
#02 pc 0x0000000000721d90 /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+208)
#03 pc 0x0000000000424f94 /apex/com.android.art/lib64/libart.so (art::Thread::RunCheckpointFunction()+140)
#04 pc 0x000000000077f90c /apex/com.android.art/lib64/libart.so (artTestSuspendFromCode+48)
#05 pc 0x000000000046113c /apex/com.android.art/lib64/libart.so (art_quick_test_suspend+156)
at android.os.Parcel.nativeWriteString8 (Native method)
at android.os.Parcel.writeString8NoHelper (Parcel.java:1141)
at android.os.Parcel$ReadWriteHelper.writeString8 (Parcel.java:482)
at android.os.Parcel.writeString8 (Parcel.java:1120)
at android.app.Notification.writeToParcelImpl (Notification.java:3211)
at android.app.Notification.writeToParcel (Notification.java:3099)
at android.os.Parcel.writeTypedObject (Parcel.java:2191)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:6987)
at android.app.Service.startForeground (Service.java:743)
at com.transistorsoft.locationmanager.service.AbstractService.c (SourceFile:1)
at com.transistorsoft.locationmanager.service.AbstractService.a (SourceFile:8)
at com.transistorsoft.locationmanager.service.TrackingService.onStartCommand (unavailable:1)
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5243)
at android.app.ActivityThread.-$$Nest$mhandleServiceArgs (unavailable)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2447)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8762)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
batchSync: true, maxDaysToPersist: 7,
You should probably provide a maxBatchSize in order to prevent potentially 7 days of records being loaded into memory.
Good call, I was under the impression the autoSyncTheshold would already make sure each request got that many records, but reading the docs again that's of course not true. I expect that in practice users log into the app at the start of their working day, and log back out near the end. When logging out, I call destroyLocations(), which should get rid of old records, but there might be a scenario I haven't kept in mind there (and aside from that, 7 days is definitely excessive for my actual use case).
I'll decrease the location persistence and add the maxBatchSize to see if it helps for these devices.
Is there anything else that sticks out to you, that could have caused issues?
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.