redux-persist: Seeing outofmemory errors on ios in asyncstorage code
Hi, using react-native-persist 5.10.0 and react-native 0.59.9, I am seeing several crashes lately in our production app like:
Error · Out of memory
[native code]stringify
node_modules/redux-persist/lib/createPersistoid.js:90:57writeStagedState
node_modules/redux-persist/lib/createPersistoid.js:78:6processNextKey
node_modules/react-native/Libraries/Core/Timers/JSTimers.js:152:6_callTimer
node_modules/react-native/Libraries/Core/Timers/JSTimers.js:414:17callTimers
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:366:47value
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:106:26
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:314:8value
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:105:17value
Could this be due to trying to store too much data in AsyncStorage? I am thinking of trying out https://github.com/bhanuc/react-native-fs-store at the RN level to drop-in this replacement for AsyncStorage … do you know if redux-persist would work with it?
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 9
- Comments: 24
I’m still chasing this … I updated everything to RN 0.61 (because aysnc storage was updated) and the symptoms changed (redux persist is no longer in the stack trace) but it does seem still related because I am updating state with every keystroke to a persisted reducer. My working theory is while doing this memory is consumed and not released fast enough (XCode profiling bears this out, although there does not appear to be a leak, just a surge in memory usage).
Just tried updating to redux-persist 6.0.0 and adding a throttle of 3000 to that reducer and explicitly flushing it when the state is cleared (to avoid it coming back due to throttle delay later). Testing now … it takes a while because this is not reliably reproducible.
Hope this helps; I will let you know what happens.
Same issue here. It seems like this problem happens when a device is really stressed by some large payload.
I think
JSON.stringifyused insidedefaultSerializefunction here https://github.com/rt2zz/redux-persist/blob/master/src/createPersistoid.js#L140is the cause. When the data to serialize is too big, it fails.
My current workaround is to use kind of “best effort” strategy to serialize. It will not store new data or remove the existing data, just to avoid the app from crashing.
I use redux-persist 6.0.0, Expo SDK36, AsyncStorage from react-native.
I also check the stored data when initializing screen and remove excessive data, because this error was happening when there was too much data in the store.
Since this error is quite hard to replicate, so I haven’t tested this solution in the production yet. But I will update when I found out it fixed it or not.
I hope someone will come up with better solution though. Any suggestion is helpful.
@dchersey @summerkiflain just to follow up here - out of curiosity, I have tried swapping out
redux-persist-expo-filesystemwith SqlLite storage (redux-persist-sqlite-storage), and I am still seeing this error, so I know it’s not specific to the storage mechanism now. I’m on Expo SDK37 and redux-persist 5.10.0.Facing same issue, but I am also using
redux-persist-expo-filesystemas storage engine, I thought it did not had any size limitations. anyone having an idea whats it about or how to deal with it?Thanks for the clues, @vovkasm. Here’s a workaround that removes the extra layer of serialization in
stagedStateby doing all the serialization in the storage layer instead:I’m hoping this will reduce the out-of-memory errors I see in production.
I think this is a complex problem that cant be fixed in one place. But I can identify at least one place that effectively double memory consumption at persist times.
Here:
stagedState, than it create 3rd copy by callserializeagain and oops, OutOfMemory.We in our application have state which persistent part contained in 4-5Mb json file. And sometimes we seen these crashes.
@summerkiflain when you set serialize & deserialize to false then you have to handle case in which existing data which is already deserialize