Как да намалим разпределението на паметта?

Пиша приложение за android. Заради целта трябва да (вмъкна) кеш моя потребителски списък с размер 10 mb в sqlite db. Когато потребителското задейства api извикване, изпращам входния поток до BufferedReader и използвам char[] buffer = new char[2048]; като парче, защото ако чета входен поток ред по ред, скриптът не продължава (мисля, че това причинява от моето 10mb тяло е един ред и е твърде голямо за четене) . Когато това се случи, използването на паметта ми се увеличава до 90mb от 10mb стабилно. кодът е по-долу

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 mb тяло от apicall, защо използването на паметта на моето приложение (java) се увеличава с 80 mb вместо с 10 mb и решението?

След като този метод върне резултат от низ, аз го използвам за инициализиране на json обект. И след това използвам този json, за да инициализирам моите екземпляри на обекти. След тази операция използването на паметта намалява до 320 mb.

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
ако четете 10MB stringBuilder ще отнеме 20MB и след това Result още 20MB ... също разпределението на s във всяка итерация също ще отнеме кумулативно 20MB ... за 10MB JSON очевидно би било по-добре да използвате някакъв анализатор на поток JSON   -  person Selvin    schedule 18.07.2018
comment
@Selvin е абсолютно прав. Ето примерни решения, които да следвате: 1. stackoverflow .com/questions/16902425/ 2. memorynotfound. com/   -  person Arseny Levin    schedule 18.07.2018
comment
все още чакам примерен код, който отговаря бързо за 10mb тяло на публикация и намалява разпределението на паметта след използването на respnose class end :(   -  person m3rt_ali    schedule 20.07.2018
comment
всеки от тях работи, когато дадете потока на gson.fromJson() той изчезва, не можах да намеря никакво предложение без разкъсване   -  person m3rt_ali    schedule 26.07.2018