Memory exception in gson.fromJson ()

I use the following code to convert a Json string (strWebserviceResult) to my Object:

EntMyClass entMyClass = gson.fromJson(strWebserviceResult,EntMyClass.class); 

When strWebserviceResult is large (about 2.5 MB), I get an Out of Memory exception on this line on Android phone devices that are not on a tablet PC that has a lot of memory.

How can i solve this.

Does anyone have any suggestions?

 05-26 15:52:49.607: E/dalvikvm-heap(2078): Out of memory on a 9200-byte allocation. 05-26 15:52:49.618: E/dalvikvm(2078): Out of memory: Heap Size=31879KB, Allocated=27693KB, Bitmap Size=936KB, Limit=32768KB 05-26 15:52:49.618: E/dalvikvm(2078): Extra info: Footprint=31879KB, Allowed Footprint=31879KB, Trimmed=7400KB 05-26 15:52:49.618: E/AndroidRuntime(2078): FATAL EXCEPTION: Thread-19 05-26 15:52:49.618: E/AndroidRuntime(2078): java.lang.OutOfMemoryError: (Heap Size=31879KB, Allocated=27693KB, Bitmap Size=936KB) 05-26 15:52:49.618: E/AndroidRuntime(2078): at java.util.ArrayList.add(ArrayList.java:123) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:664) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:624) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:51) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:117) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:76) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:54) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:663) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:624) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:51) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:80) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:101) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:67) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:52) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.Gson.fromJson(Gson.java:551) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.Gson.fromJson(Gson.java:498) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.Gson.fromJson(Gson.java:467) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.Gson.fromJson(Gson.java:417) 05-26 15:52:49.618: E/AndroidRuntime(2078): at com.google.gson.Gson.fromJson(Gson.java:389) 05-26 15:52:49.618: E/AndroidRuntime(2078): at org.mabna.order.businessLayer.BoWebService.getDataForUpdate(BoWebService.java:188) 05-26 15:52:49.618: E/AndroidRuntime(2078): at org.mabna.order.ui.ActToolDataExchange.threadGetDataForFullUpdate(ActToolDataExchange.java:371) 05-26 15:52:49.618: E/AndroidRuntime(2078): at org.mabna.order.ui.ActToolDataExchange.access$9(ActToolDataExchange.java:362) 05-26 15:52:49.618: E/AndroidRuntime(2078): at org.mabna.order.ui.ActToolDataExchange$33.run(ActToolDataExchange.java:603) 05-26 15:52:49.618: E/AndroidRuntime(2078): at org.mabna.order.utils.Utilities$5.run(Utilities.java:778) 
+7
source share
4 answers

Try using the fromJson method, which uses JsonReader instead. This should allow you not to require the entire input line to be in memory at a time. Here is a sample code:

  final HttpURLConnection c = (HttpURLConnection) url.openConnection(); final InputStreamReader isr = new InputStreamReader(c.getInputStream()); final JsonReader reader = new JsonReader(isr); final EntMyClass entMyClass = GSON.fromJson(reader, EntMyClass.class); reader.close(); c.disconnect(); 
+5
source

As with the other post, I would ask if there is a way to avoid using a lot of memory in your application. If you can do this, this will be the best solution. If your application really needs so much memory, you can try setting android:largeHeap="true" for your application in the manifest. Here is the link:

http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap

Watch this video for more information:

http://www.youtube.com/watch?v=_CruQY55HOk

+5
source

First of all. Do you really need to load 2.5 MB of data into memory?
First, a large string is created, then it is parsed (other objects in memory), and then a huge instance of EntMyClass is created. This approach is really ineffective.

I think you have a List in this object. Having only the information you provide, I suggest transferring the data to the database. You can then create an adapter to display data in a ListView.

There are many ways to do this. I use the Jackson library because it is the fastest; GSON should have similar features.

Assuming you have a list in this object below, an example of how to store a json array in a database is given:

  //create parser final JsonParser jsonParser = objectMapper.getJsonFactory().createJsonParser(inputStream); JsonToken jsonToken = jsonParser.nextToken(); while ((jsonToken = jsonParser.nextToken()) != null && jsonToken != JsonToken.END_ARRAY) { //map json object to ItemClass final ItemClass item = jsonParser.readValueAs(ItemClass.class); //store in database itemDAO.insert(item); } 

And combine it with a database transaction, not only the data will be rolled back in case of an error, but also more efficient.

+1
source

Please read the answer from gson author - here

And my 5 cents:

  JsonReader r = null; try { Reader reader = new BufferedReader(new InputStreamReader(is)); r = new JsonReader(reader); result = gson.fromJson(r, clazz); } finally { if (null != r) { r.close(); } } 
0
source

All Articles