gson.fromJson()中的内存不足exception

我使用下面的代码将Jsonstring(strWebserviceResult)转换为我的对象:

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

strWebserviceResult很大(大约2.5 MB)时,我在Android手机设备上的这一行上得到了内存不足exception,而不是在具有较大内存的平板电脑上。

我该如何解决这个问题。

有人有什么build议吗?

 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) 

Solutions Collecting From Web of "gson.fromJson()中的内存不足exception"

尝试使用将JsonReader作为input的fromJson方法。 这应该允许你不需要整个inputstring一次在内存中。 以下是一些示例代码:

  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(); 

至于其他职位,我会问是否有任何方法来避免您的应用程序使用大量的内存。 如果你能做到这一点,那将是最理想的解决scheme。 如果您的应用程序真的需要那么多的内存,您可以尝试在清单中为您的应用程序设置android:largeHeap="true" 。 这里是参考:

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

看到这个video了解更多信息:

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

首先。 你真的需要将2.5MB的数据加载到内存中吗?
首先创build一个大的string,然后parsing(内存中的另一个对象),然后创build一个巨大的EntMyClass实例。 这种方法真的是效率低下。

我猜你在这个对象中有List。 只有你提供的信息,我build议将数据stream入数据库。 然后你可以创build适配器来在ListView中显示数据。

有很多方法如何做到这一点。 我使用Jackson库是因为速度最快,GSON应该有类似的function。

假设你在这个对象中有一个列表,下面是示例如何在数据库中存储json数组:

  //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); } 

并且用数据库事务包围它,不仅数据会在出错的情况下回滚,而且也更有效率。

请阅读gson的作者的回答 – 在这里

而我的5美分:

  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(); } }