使用OkHttpClient在TC75(8mb RAM)上解析36972行JSON响应时,我得到了java.lang.OutOfMemoryError。当我尝试调用response.body()。string()
时会出现问题E/dalvikvm-heap: Out of memory on a 26525298-byte allocation.
我试图将数据保存在StringBuilder和流式JsonReader中[在此答案中]。[1]
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(...).build();
try {
Response response = client.newCall(request).execute();
JsonReader jsonReader = new JsonReader(new StringReader(response.body().string()));
... (loads of JsonReader parsing)
} catch (IOException | ParseException e) {
e.printStackTrace();
}
在Samsung S6 Active(3GB内存)上运行时,应用程序可以轻松解析此JSON。如何通过如此有限的RAM避免内存不足错误?它甚至可能吗?
堆栈跟踪:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.at.project, PID: 4409
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.OutOfMemoryError
at java.lang.String.<init>(String.java:255)
at java.lang.String.<init>(String.java:228)
at com.squareup.okhttp.ResponseBody.string(ResponseBody.java:83)
at com.at.project.activities.LoginNewActivity$UserLoginTask.getOEMPartPricingJson(LoginNewActivity.java:1496)
at com.at.project.activities.LoginNewActivity$UserLoginTask.downloadAnyNewJson(LoginNewActivity.java:860)
at com.at.project.activities.LoginNewActivity$UserLoginTask.checkForatDprojectdates(LoginNewActivity.java:746)
at com.at.project.activities.LoginNewActivity$UserLoginTask.checkForUpdates(LoginNewActivity.java:659)
at com.at.project.activities.LoginNewActivity$UserLoginTask.doInBackground(LoginNewActivity.java:486)
at com.at.project.activities.LoginNewActivity$UserLoginTask.doInBackground(LoginNewActivity.java:465)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
答案 0 :(得分:0)
流式解析器设计用于返回XML或json等元素,因为它们是从数据流中解析出来的。它们通常允许用户解析总内存使用率较低的大型文档,或者在开始对正在解析的文件执行有用的操作之前减少缓冲时间。
Jackson Streaming解析器是用java编写的。它可能会做你需要的。我确信还有其他流媒体json解析器。
对于低内存系统,您可能无法将所有数据吸收到String或StringBuilder中。相反,您将把流传递给流解析器并在元素出现时处理回调。您需要抛弃未使用的和不必要的元素,而不是尝试构建完整json文件的解析树。
答案 1 :(得分:0)