esi*_*ver 12 java android json out-of-memory
我有一个Android客户端,通过REST-ful端点和JSON与服务器通信.因此,我需要在将其转换为Hash之前检索完整的服务器响应.我有这个代码(在互联网上找到的地方):
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
代码在大多数情况下都有效,但是我看到来自具有OutOfMemory异常的客户端在该字段中崩溃的报告:
while ((line = reader.readLine()) != null) {
Run Code Online (Sandbox Code Playgroud)
完整的堆栈跟踪是:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1102)
Caused by: java.lang.OutOfMemoryError
at java.lang.String.(String.java:468)
at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
at java.lang.StringBuilder.toString(StringBuilder.java:664)
at java.io.BufferedReader.readLine(BufferedReader.java:448)
at com.appspot.myapp.util.RestClient.convertStreamToString(RestClient.java:303)
at com.appspot.myapp.util.RestClient.executeRequest(RestClient.java:281)
at com.appspot.myapp.util.RestClient.Execute(RestClient.java:178)
at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1178)
at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
Run Code Online (Sandbox Code Playgroud)
我的问题:除了从服务器发送更小的数据块之外,还有什么方法可以解决这个问题吗?
谢谢!
一般来说,答案是否定的,但是您当然可以调整导致内存不足的条件。特别是,如果您在流之前发送字符串长度,您将能够创建一个内部具有正确数组大小的 StringBuilder。数组在创建后无法调整大小,因此,如果 StringBuilder 中的数组容量用完,则实现必须分配一个新数组(通常是大小的两倍,以避免过多调整大小),然后复制旧数组内容。考虑大小为 X 的流,要调整正好是 X-1 容量的 StringBuilder 的大小,您需要几乎 X*3 的内存量。调整 StringBuilder 的大小以避免调整大小将允许您将更大的流压缩到内存中。
您可能想要做的另一件事是调整服务器进程可用的内存量。启动服务器进程时使用 -Xmx1024m 等开关。
当然,最好修改算法以不需要将整个流保存在内存中。它将使您能够使用相同数量的硬件处理更多的客户端。
| 归档时间: |
|
| 查看次数: |
19581 次 |
| 最近记录: |