Details
-
New Feature
-
Status: Open
-
Minor
-
Resolution: Unresolved
-
None
-
None
Description
As reported in https://github.com/litehelpers/Cordova-sqlite-storage/issues/18: when an array with a very large number of JSON objects is sent from Javascript to Java, I would encounter a memory problem in JSON as called by CordovaPlugin.execute():
E/art (22291): Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 20 free bytes and 20B until OOM" (recursive case)
E/art (22291): "JavaBridge" prio=5 tid=25 Runnable
E/art (22291): | group="main" sCount=0 dsCount=0 obj=0x12de6820 self=0xb73ae620
E/art (22291): | sysTid=22377 nice=0 cgrp=apps sched=0/0 handle=0xb73aead8
E/art (22291): | state=R schedstat=( 0 0 0 ) utm=653 stm=94 core=1 HZ=100
E/art (22291): | stack=0xa4ee1000-0xa4ee3000 stackSize=1036KB
E/art (22291): | held mutexes= "mutator lock"(shared held)
E/art (22291): at java.util.LinkedHashMap.addNewEntry(LinkedHashMap.java:195)
E/art (22291): at java.util.HashMap.put(HashMap.java:403)
E/art (22291): at org.json.JSONObject.put(JSONObject.java:264)
E/art (22291): at org.json.JSONTokener.readObject(JSONTokener.java:385)
E/art (22291): at org.json.JSONTokener.nextValue(JSONTokener.java:100)
E/art (22291): at org.json.JSONTokener.readArray(JSONTokener.java:430)
E/art (22291): at org.json.JSONTokener.nextValue(JSONTokener.java:103)
E/art (22291): at org.json.JSONTokener.readObject(JSONTokener.java:385)
E/art (22291): at org.json.JSONTokener.nextValue(JSONTokener.java:100)
E/art (22291): at org.json.JSONTokener.readArray(JSONTokener.java:430)
E/art (22291): at org.json.JSONTokener.nextValue(JSONTokener.java:103)
E/art (22291): at org.json.JSONArray.<init>(JSONArray.java:92)
E/art (22291): at org.json.JSONArray.<init>(JSONArray.java:108)
E/art (22291): at org.apache.cordova.CordovaPlugin.execute(CordovaPlugin.java:64)
E/art (22291): at org.apache.cordova.PluginManager.execHelper(PluginManager.java:242)
E/art (22291): at org.apache.cordova.PluginManager.exec(PluginManager.java:227)
E/art (22291): at org.apache.cordova.ExposedJsApi.exec(ExposedJsApi.java:53)
E/art (22291): at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native method)
E/art (22291): at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:53)
E/art (22291): at android.os.Handler.dispatchMessage(Handler.java:102)
E/art (22291): at android.os.Looper.loop(Looper.java:135)
E/art (22291): at android.os.HandlerThread.run(HandlerThread.java:61)
The workaround, which took me some hard work to develop and test, is to send my data as a flat array which the Java code has to interpret very carefully.
In addition, in case the Java code attempts to create an array with a very large number of JSON objects in order to send a response I get similar problem. The workaround was again to format the response data as a flat array and interpret it very carefully on the Javascript side.
While I do have a workaround I find this to be very clumsy and hope we can find a better solution. I am happy to make an isolated test plugin to reproduce and demonstrate this issue if the Apache Cordova project is serious about trying to fix it.