JSONObject toString()导致1495472字节分配的内存不足

时间:2013-03-11 19:31:29

标签: java android json out-of-memory

我使用以下设备测试我的应用:

enter image description here

我发布的JSON字符串大小约为498467字节(0.48MB)。

当我的应用程序同步此数据时,当我toString() JSONObect时,它会失败,例如:

JSONObject jsonObj = new JSONObject();
...
ClientMyAppApi.Upload(getContext(), account.name, jsonObj.toString()); // Out of memory here

这是LogCat成绩单:

D/dalvikvm(21964): GC_CONCURRENT freed 690K, 12% free 10892K/12295K, paused 5ms+9ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 606K, 9% free 11196K/12295K, paused 57ms
I/dalvikvm-heap(21964): Grow heap (frag case) to 11.630MB for 662266-byte allocation
D/dalvikvm(21964): GC_FOR_ALLOC freed 431K, 13% free 11411K/12999K, paused 61ms
I/dalvikvm-heap(21964): Grow heap (frag case) to 12.157MB for 993394-byte allocation
D/dalvikvm(21964): GC_FOR_ALLOC freed 646K, 17% free 11734K/14023K, paused 63ms
I/dalvikvm-heap(21964): Grow heap (frag case) to 12.947MB for 1490086-byte allocation
D/dalvikvm(21964): GC_FOR_ALLOC freed 970K, 22% free 12220K/15495K, paused 69ms
D/AdapterSync(21964): uploadNewContent() JSON request size: 498468
D/dalvikvm(21964): GC_CONCURRENT freed 3172K, 30% free 10892K/15495K, paused 5ms+26ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 606K, 28% free 11195K/15495K, paused 56ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 431K, 27% free 11411K/15495K, paused 59ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 646K, 25% free 11734K/15495K, paused 61ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 970K, 22% free 12219K/15495K, paused 69ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 1459K, 25% free 11742K/15495K, paused 74ms
D/dalvikvm(21964): GC_CONCURRENT freed 664K, 18% free 12726K/15495K, paused 17ms+12ms
D/dalvikvm(21964): GC_CONCURRENT freed 1930K, 18% free 12723K/15495K, paused 22ms+10ms
D/dalvikvm(21964): GC_FOR_ALLOC freed 13K, 18% free 12716K/15495K, paused 70ms
I/dalvikvm-heap(21964): Forcing collection of SoftReferences for 1495472-byte allocation
D/dalvikvm(21964): GC_BEFORE_OOM freed 9K, 18% free 12707K/15495K, paused 114ms
E/dalvikvm-heap(21964): Out of memory on a 1495472-byte allocation.
I/dalvikvm(21964): "SyncAdapterThread-1" prio=5 tid=20 RUNNABLE
I/dalvikvm(21964):   | group="main" sCount=0 dsCount=0 obj=0x4101ac78 self=0x2f5198
I/dalvikvm(21964):   | sysTid=22098 nice=10 sched=0/0 cgrp=bg_non_interactive handle=3325456
I/dalvikvm(21964):   | schedstat=( 5787106417 2132935545 325 ) utm=552 stm=26 core=0
I/dalvikvm(21964):   at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:~94)
I/dalvikvm(21964):   at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132)
I/dalvikvm(21964):   at java.lang.StringBuilder.append(StringBuilder.java:124)
I/dalvikvm(21964):   at libcore.net.UriCodec.appendEncoded(UriCodec.java:119)
I/dalvikvm(21964):   at libcore.net.UriCodec.encode(UriCodec.java:133)
I/dalvikvm(21964):   at java.net.URLEncoder.encode(URLEncoder.java:57)
I/dalvikvm(21964):   at org.apache.http.client.utils.URLEncodedUtils.encode(URLEncodedUtils.java:184)
I/dalvikvm(21964):   at org.apache.http.client.utils.URLEncodedUtils.format(URLEncodedUtils.java:163)
I/dalvikvm(21964):   at org.apache.http.client.entity.UrlEncodedFormEntity.<init>(UrlEncodedFormEntity.java:57)
I/dalvikvm(21964):   at com.myapp.utils.NetworkUtils.makeHttpRequestWithParams(NetworkUtils.java:177)
I/dalvikvm(21964):   at com.myapp.client.ClientMyAppApi.MakeRequest(ClientMyAppApi.java:208)
I/dalvikvm(21964):   at com.myapp.client.ClientMyAppApi.Upload(ClientMyAppApi.java:395)
I/dalvikvm(21964):   at com.myapp.syncadapter.AdapterSync.uploadNewContent(AdapterSync.java:744)
I/dalvikvm(21964):   at com.myapp.syncadapter.AdapterSync.onPerformSync(AdapterSync.java:120)
I/dalvikvm(21964):   at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:247)
W/dalvikvm(21964): threadid=20: thread exiting with uncaught exception (group=0x409c01f8)
E/AndroidRuntime(21964): FATAL EXCEPTION: SyncAdapterThread-1
E/AndroidRuntime(21964): java.lang.OutOfMemoryError
E/AndroidRuntime(21964):    at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
E/AndroidRuntime(21964):    at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132)
E/AndroidRuntime(21964):    at java.lang.StringBuilder.append(StringBuilder.java:124)
E/AndroidRuntime(21964):    at libcore.net.UriCodec.appendEncoded(UriCodec.java:119)
E/AndroidRuntime(21964):    at libcore.net.UriCodec.encode(UriCodec.java:133)
E/AndroidRuntime(21964):    at java.net.URLEncoder.encode(URLEncoder.java:57)
E/AndroidRuntime(21964):    at org.apache.http.client.utils.URLEncodedUtils.encode(URLEncodedUtils.java:184)
E/AndroidRuntime(21964):    at org.apache.http.client.utils.URLEncodedUtils.format(URLEncodedUtils.java:163)
E/AndroidRuntime(21964):    at org.apache.http.client.entity.UrlEncodedFormEntity.<init>(UrlEncodedFormEntity.java:57)
E/AndroidRuntime(21964):    at com.myapp.utils.NetworkUtils.makeHttpRequestWithParams(NetworkUtils.java:177)
E/AndroidRuntime(21964):    at com.myapp.client.ClientMyAppApi.MakeRequest(ClientMyAppApi.java:208)
E/AndroidRuntime(21964):    at com.myapp.client.ClientMyAppApi.Upload(ClientMyAppApi.java:395)
E/AndroidRuntime(21964):    at com.myapp.syncadapter.AdapterSync.uploadNewContent(AdapterSync.java:744)
E/AndroidRuntime(21964):    at com.myapp.syncadapter.AdapterSync.onPerformSync(AdapterSync.java:120)
E/AndroidRuntime(21964):    at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:247)

解决此内存不足问题的最佳方法是什么以及如何解决?

3 个答案:

答案 0 :(得分:1)

虽然这不是一个非常“优雅”的解决方案,但您可以尝试将android:largeHeap="true"添加到清单中。尝试运行此操作,但我不建议将其保留在那里,因为它可能会导致一些性能问题 也就是说,如果它没有解决内存不足问题,它可能在JSON或代码本身的某个地方。

答案 1 :(得分:0)

您可以尝试streaming approach employed by Jackson:似乎allow incremental writing没有内存开销,需要在编写之前以String形式序列化整个JSON对象的Android JSON库在连接流上。

答案 2 :(得分:-3)

我查看了我的AVD配置。我有相同的RAM量。但是,我有更大的堆大小,如48 M.我认为,值得尝试。

Goog运气好。