【发布时间】:2021-12-24 09:18:48
【问题描述】:
我收到以下 OutOfMemoryError 异常尝试通过 API 的响应分页
原因:java.lang.OutOfMemoryError:无法分配 37748744 字节分配,25165824 空闲字节和 24MB 直到 OOM,目标占用空间 268261936,增长限制 268435456 在 java.util.Arrays.copyOf(Arrays.java:3257) 在 java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124) 在 java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:649) 在 java.lang.StringBuilder.append(StringBuilder.java:203) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.readAll(INatCall.java:105) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.restCalliNat(INatCall.java:56) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.restCalliNat(INatCall.java:75) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.restCalliNat(INatCall.java:75) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.restCalliNat(INatCall.java:75) 在 com.richmondgamesstudio.inattaxonomytreeviewer.utils.INatCall.doInBackground(INatCall.java:42)
有没有更有效的方法通过休息来处理大量数据? 我的应用程序调用返回用户“条目”的 API。 API 的最大页数为 200。大多数用户将拥有超过 200 个条目,这在大多数情况下都很好。我的应用程序可以分页并说明这一点。但是,有些用户将拥有 +2000 个条目,而我的应用程序在尝试遍历这些更大的集合时内存不足。 我的问题是:
- 有没有办法增加我的 android 应用程序可以使用的内存量 用吗?
- 有哪些方法可以优化以下代码以减少使用 记忆力?
递归休息调用
private JSONArray restCall(URL url, JSONArray results) {
Log.d(TAG, "restCalliNat: Start");
InputStream is = null;
int totalResults = 0;
int perPage = 0;
JSONArray newResults = new JSONArray();
try {
is = url.openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd); //<-- LINE 56
is.close();
rd.close();
JSONObject json = new JSONObject(jsonText);
newResults = json.getJSONArray("results");
totalResults = (int) json.get("total_results");
perPage = (int) json.get("per_page");
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
if (results != null) {
newResults = concatArray(results, newResults);
}
if (totalResults > page*perPage) {
newResults = restCall(updatePageCount(url), newResults);
}
return newResults;
}
在每个新页面上,新页面都会连接起来,直到我拥有所有条目为止。
private JSONArray concatArray(JSONArray arr1, JSONArray arr2) {
JSONArray result = new JSONArray();
try {
for (int i = 0; i < arr1.length(); i++) {
result.put(arr1.get(i));
}
for (int i = 0; i < arr2.length(); i++) {
result.put(arr2.get(i));
}
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
将 API 响应转换为字符串
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp); //<--- LINE 105
}
return sb.toString();
}
【问题讨论】:
标签: java android rest out-of-memory