[ 
https://issues.apache.org/jira/browse/CB-9353?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14627861#comment-14627861
 ] 

Chris Brody commented on CB-9353:
---------------------------------

I made a plugin based off a fork of cordova-ext-echo that can be used to 
reproduce this issue at: 
https://github.com/brodybits/cordova-ext-echo-repeat-object-test

This plugin adds three test functions, working on both Android and iOS:
- Echo.array_object_count(array, callback) - send an array object to Android or 
iOS native implementation and get the number of elements in the callback
- Echo.repeat_it(object, n, callback) - send an object to Android or iOS native 
implementation and get an array with the object repeated n times in the callback
- Echo.build_test(n, callback) - get an array of n objects from the Android or 
iOS native implementation in the calllback

My test program is just a bunch of Javascript that I added to the onDeviceReady 
function in www/js/index.js or assets/www/js/index.js:


        // Echo object:
        var Echo = cordova.require('org.apache.cordova.plugins.echo.Echo');

        // Small array count test Javascript JSON --> platform:
        Echo.array_object_count(['a',1,null,2], function(v) {
          alert("Small array count is: " + v);
        });

        // Small repeat test platform JSON --> Javascript:
        Echo.repeat_it({a: 1, b: 2}, 4, function(v) {
          alert("Small repeat result: " + JSON.stringify(v));
        });

        // Small repeat build test platform JSON --> Javascript:
        Echo.build_test(4, function(v) {
          alert("Small build_test result: " + JSON.stringify(v));
        });

        // iterator:
        var i;
        // big test size:
        var big_array_count  = 200000;
        var big_result_count = 400000;

        //** ** XXX Big object array test - BROKEN [CRASHING] ON ANDROID:

        // Big object array test Javascript JSON --> platform:
        var big_object_array = [];
        for (i=0; i<big_array_count; ++i) big_object_array.push({a:"a", 
b:["a",1,"b",2]});
        Echo.array_object_count(big_object_array, function(v) {
          alert("Big object array count is: " + v);
        });

        // */

        //** ** Big tests WORKING on Android:

        // flat test Javascript JSON --> platform:
        var big_flat_array = [];
        for (i=0; i<big_array_count; ++i) big_flat_array.push("{a:'a', 
b:['a',1,'b',2]}");
        Echo.array_object_count(big_flat_array, function(v) {
          alert("flat array count is: " + v);
        });

        // Big repeat test platform JSON --> Javascript:
        Echo.repeat_it({a:"a", b:1234, c:5678}, big_result_count, function(v) {
          alert("Big repeat test done");
        });

        // */

        //** ** XXX Big repeat build test - BROKEN [CRASHING] ON ANDROID:

        // Big repeat build test platform JSON --> Javascript:
        Echo.build_test(big_result_count, function(v) {
          alert("Big repeat build test done");
        });

        // */

Note that each "big test" section starts with "//**" and ends with "// */", so 
it is very easily to remove the first "/" to comment the section out (and add 
the "/" back again to re-enable the section).

The big object array test shows the problem where an array with a large number 
of JSON objects from Javascript to Java causes a crash in 
org.apache.cordova.CordovaPlugin.execute() when it attempts to decode the JSON.

The big repeat build test shows the problem where the Java code attempts to 
create an array with a large number of JSON objects to send back to Javascript 
but crashes (with the memory issue).

Note that all of the scenarios in the test program work fine in the iOS 
implementation.

> Memory issue in Android version when passing a large number of JSON objects 
> in either direction
> -----------------------------------------------------------------------------------------------
>
>                 Key: CB-9353
>                 URL: https://issues.apache.org/jira/browse/CB-9353
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: Android
>            Reporter: Chris Brody
>
> 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.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to