Как уменьшить выделение памяти?

Я пишу приложение для Android. Из-за цели я должен (вставить) кэшировать свой список пользователей размером 10 МБ в sqlite db. Когда пользователь запускает вызов API, я отправляю поток ввода в BufferedReader и использую char[] buffer = new char[2048]; в качестве фрагмента, потому что, если я читаю поток ввода построчно, сценарий не продолжается (я думаю, что это приводит к тому, что из моего тела 10 МБ получается одна строка, и она слишком велика для чтения) . Когда это происходит, использование моей памяти увеличивается до 90 МБ со стабильных 10 МБ. код ниже

private String getResult() {
    String Result = "";


    try {
   ....    
        StringBuilder stringBuilder = new StringBuilder();
        int HttpResult = connection.getResponseCode();
        if (HttpResult == HttpURLConnection.HTTP_OK) {

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), CharsetNames.Utf8.value));
            String line = null;
            char[] buffer = new char[2048];
            int count;
            while ((count = reader.read(buffer)) != -1) {
                String s = new String(buffer, 0, count);
                stringBuilder.append(s);

            }
            reader.close();
            Result = stringBuilder.toString();
        } else {
            Result = null;
        }
    } catch (InterruptedIOException e) {

    } catch (IOException e) {
        e.printStackTrace();
        Tools.ShowStandartErrorToast();
    }
    return Result;
}

1_ почему, когда я красный 10 МБ тела от apicall, почему использование памяти моего приложения (java) увеличивается на 80 МБ вместо 10 МБ и решение?

После того, как этот метод возвращает строковый результат, я использую его для инициализации объекта json. И затем я использую этот json для инициализации своих экземпляров объектов. После этой операции использование памяти уменьшается до 320 мб.

protected Result doInBackground(Parameter Parameter) {

    ...........
       ApiHelper = new ApiHelper(getSelectedService(), parameter.getAsJson());
       String resultString = ApiHelper.getResult();
       result = setResult(resultString);
    ...........
}

public class UserListResponse extends BaseResponse {

    public static final String UserList_FIELD_NAME = "UserList";
    public List<User> UserList;

    public UserListResponse(String baseStringResult) {
        try {
            this.baseJsonResult = new JSONObject(baseStringResult);

        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            this.baseJsonResult = new JSONObject();
        }
    }

    @Override
    protected void mapFields() {


        if (baseJsonResult.has(UserList_FIELD_NAME) && !baseJsonResult.isNull(UserList_FIELD_NAME)) {
            try {

                JSONArray jaPerson = baseJsonResult.getJSONArray(UserList_FIELD_NAME);
                UserList = new ArrayList<>(jaPerson.length());

                for (int i = 0; i < jaPerson.length(); i++) {
                    JSONObject joPersonInfo = jaPerson.getJSONObject(i);
                    User pi = new User();
                    pi.init(joPersonInfo);
                    UserList.add(pi);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}

2_ Если причина в том, что я в основном использую строковые поля, как я могу освободить эти строковые поля. Я думаю, что они продолжают жить, даже если я объявляю их методом.

Я использовал System.gc() везде, где это было возможно, но это не повлияло на использование памяти.


person m3rt_ali    schedule 18.07.2018    source источник
comment
если вы читаете 10 МБ, stringBuilder займет 20 МБ, а затем Result еще 20 МБ ... также выделение s на каждой итерации также займет в совокупности 20 МБ ... для 10 МБ JSON, очевидно, было бы лучше использовать какой-нибудь потоковый синтаксический анализатор JSON   -  person Selvin    schedule 18.07.2018
comment
@Selvin абсолютно прав. Вот примеры решений: 1. stackoverflow .com/questions/16902425/ 2. память не найдена. ком/   -  person Arseny Levin    schedule 18.07.2018
comment
все еще жду пример кода, который быстро отвечает на 10-мегабайтное тело сообщения и уменьшает выделение памяти после использования класса respnose end :(   -  person m3rt_ali    schedule 20.07.2018
comment
любой из них работал, когда вы передаете поток gson.fromJson(), он исчезает, не может найти никаких предложений без фрагментации   -  person m3rt_ali    schedule 26.07.2018