У меня есть приложение для Android. Во-первых, приложение выполняет синхронизацию. В этом процессе сервер отправляет на устройство объект JSON как String, с помощью которого он может создавать доступные опросные листы.
GetQuestionnairesResponse.java:
public class GetQuestionnairesResponse extends ResponseHandler
{
public GetQuestionnairesResponse(String result, AsyncRequest request)
{
super(result, request);
}
@Override
public void handleResponse()
{
DataSyncActivity caller = (DataSyncActivity) request.getCaller();
BackgroundManager bckMng = BackgroundManager.getInstance(caller);
PreferencesManager preference = PreferencesManager.getInstance(null);
boolean status = true;
int numOfWrongJsonVer = 0;
int totalNumOfQuestionnaires = 0;
// Handle data from server
// Creating JSON Parser instance
try
{
QuestionnaireDataSource questionnaireDS = new QuestionnaireDataSource(caller);
questionnaireDS.open();
JSONArray jArr = new JSONArray(result);
JSONObject j = null;
totalNumOfQuestionnaires = jArr.length();
for (int i = 0; i < jArr.length(); i++)
{
j = jArr.getJSONObject(i);
long questId = j.getLong("questionnaireId");
long surveyId = j.getLong("surveyId");
String questName = j.getString("name");
String desc = j.getString("description");
int version = j.getInt("questionnaireVersion");
int jsonVersion = j.getInt("jsonVersion");
if (jsonVersion == PreferencesManager.jsonVersion)
{
// Save the pages part
String filename = questId + "_" + version + "_" + jsonVersion + ".json";
HelpFunctions.writeJSON(filename, j.toString());
Questionnaire quest = questionnaireDS.createQuestionnaire(questId, questName, desc, surveyId, version, jsonVersion, filename);
if (quest == null)
throw new RuntimeException("Cant save the questionnaire: " + questName);
}
else
{
numOfWrongJsonVer ++;
}
}
questionnaireDS.close();
}
catch (Exception e)
{
status = false;
if (e.getMessage() != null)
Log.e(TAG, e.getMessage());
}
caller.setInSync(false);
...
}
Результат, который я получаю от сервера, анализирую его на массив Json. Результат в некоторых случаях может составлять 3 мегабайта.
Решение, которое я нашел, это добавить атрибут в manifest.xml:
android:largeHeap="true"
Он решил проблему. Я не знаю, почему, но проблема снова вернулась в последний день. Я буду рад получить предложения по решению проблемы. Проблема в том, что объект json не анализировался так, как ожидалось, поэтому он
Если JSON был изначально 3 МБ, и вы вызывали toString()
на JSONObject
, который был проанализирован из него, JSONObject
по-прежнему занимает память, плюс ему потребуется сделать выделение 3 МБ для хранения String
. Возможно, у вас не так много доступной памяти.
Но дело в OutOfMemoryError
заключается в том, что распределение, использующее последний бит ОЗУ, не обязательно виноват в том, что имеется так мало доступной ОЗУ. Большие ассигнования, скорее всего, будут тем, что подталкивает его к краю. Вероятно, у вас есть утечка памяти где-то еще в вашем приложении, и вам нужно использовать инструмент, например Eclipse MAT, чтобы найти его.
Gson
иJakson
. не используйтеlargHeap
для этой проблемы. если вы хотите конвертировать самостоятельно, вы копируете все json в память, и, поскольку ваш json очень большой (я думаю), вы получаете ошибкуOOM