Android - загрузка нескольких файлов в Async Task вызывает чрезмерное сборку мусора - PullRequest
0 голосов
/ 19 сентября 2018

Для моего приложения я получаю список URL-адресов для загрузки и сохранения в локальном хранилище с размером файла от менее 1 МБ до более 50 МБ и количеством файлов от 15 до 60.Я делаю это с помощью асинхронной задачи и следующего кода:

 new AsyncTask<String, Integer, String>() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params) {
            String etag = "";
            Log.v(TAG, "Adding " + url + " to download queue.");
            InputStream inputStream;
            try {
                URL fileURL = new URL(url);
                URLConnection urlConnection;
                urlConnection = fileURL.openConnection();
                etag = urlConnection.getHeaderField("ETag");
                inputStream = fileURL.openStream();
                DataInputStream dis = new DataInputStream(inputStream);
                byte[] buffer = new byte[1024];
                int length;
                FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory() + "<folderPath>" + fileName);
                while ((length = dis.read(buffer)) > 0) {
                    fos.write(buffer, 0, length);
                }
                inputStream.close();
                fos.close();
            } catch (FileNotFoundException e) {
                Log.e(TAG, "File not found.");
                e.printStackTrace();
            } catch (IOException e) {
                Log.e(TAG, "Error Downloading file " + fileName);
                e.printStackTrace();
            }
            return etag;
        }
}.execute();

Я не использую onProgressUpdate для чего-либо, а переопределение OnPostExecute используется для нескольких обновлений пользовательского интерфейса, таких как индикатор выполнения.Я пропустил оба, потому что я не думаю, что оба имеют отношение к GC, но я включу позже, если необходимо.

Я также попробовал вышеупомянутый код с

.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

вместо просто

.execute();

, как показано.

Использование .executeOnExecutor () приводит к гораздо более быстрой загрузке, так как файлы могут загружать много одновременно в пуле, но дает больше сборщиков мусора.Обычный .execute () работает медленнее, но дает меньше (по-прежнему много) GC.

Мои вопросы:

  1. Может кто-нибудь объяснить, почему один метод приводит к большему количеству GC, чемдругой?

  2. Как я могу исправить код загрузки, чтобы предотвратить столько GC?

Изображение журналов GC: * ​​1028 *excessive GC calls

...