Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
schlawiner
5 / 5 / 2
Регистрация: 25.05.2014
Сообщений: 21
Завершенные тесты: 1
#1

Service использует много памяти - Android

21.07.2016, 07:07. Просмотров 163. Ответов 2
Метки нет (Все метки)

Всем привет! у меня есть сервис (IntentService), который работает в отдельном процессе. Суть этого сервиса синхронизировать данные с сервера в локальную БД, это более тысячи запросов к серверу и сохранение результата в бд. Сервис работает замечательно, только есть проблема в потреблении памяти. Она может постепенно вырасти до 50МБ, потом сбросить 10-20МБ, потом опять растет и немного сбрасывает. у меня доходило до 100МБ. Когда сервис завершает работу, память вся сбрасывается и процесс успешно закрывается. Почему так происходит я не понимаю. утечка памяти или специфическая работа сборщика мусора.

Теперь перейдем непосредственно к коду. Первое - это главный метод в сервисе, который выполняет все работу:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int currentPage = 1;
        SynchronizeThreadPoolExecutor threadPoolExecutor = new SynchronizeThreadPoolExecutor(NUMBER_OF_CORES/2,
                NUMBER_OF_CORES/2,
                KEEP_ALIVE_TIME,
                KEEP_ALIVE_TIME_UNIT,
                synchBlockingQueue);
        while (true) {
            if (pageCount >= currentPage) {
                if (threadPoolExecutor.getActiveCount() < threadPoolExecutor.getMaximumPoolSize()) {
                    threadPoolExecutor.execute(new SynchronizeRunnable(currentPage,
                            new Date(timeSynchronize.getDateAndTimeLastSynchronize().getTime())));
                    currentPage++;
                }
            } else {
                break;
            }
        }
        setDateLastSynchronize(timeSynchronize);
        RealmConfiguration configuration = realm.getConfiguration();
        realm.close();
        realm = null;
        Realm.compactRealm(configuration);
Здесь создается экземпляр ThreadPoolExecutor(в данном случае моя реализация данного класса), который контролирует количество одновременно выполняемых задач. такой цикл наверное не лучшая реализация, но лучше я не придумал

Собственно сам класс SynchronizeThreadPoolExecutor
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SynchronizeThreadPoolExecutor extends ThreadPoolExecutor {
 
 
    public SynchronizeThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                         TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
 
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        remove(r);
    }
}
Здесь особо ничего интересного, просто удаляю завершенный поток из пула.

Ну и реализация Runnable, где происходит запрос и запись(для запросов использую retrofit, для бд - realm)
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class SynchronizeRunnable implements Runnable {
 
 
    HashMap<String, String> searchParam;
 
 
    public SynchronizeRunnable(int page, Date dateSynch) {
        searchParam = new HashMap<>();
        searchParam.put("modified", new SimpleDateFormat("yyyy-MM-dd")
                .format(dateSynch));
        searchParam.put("page", String.valueOf(page));
    }
 
 
    @Override
    public void run() {
 
        try {
            Response response = RetrofitRequest.getNotariesRequest(searchParam);
            List<Notary> notaries = response.getResults();
            Realm realm = Realm.getDefaultInstance();
            realm.beginTransaction();
            realm.copyToRealmOrUpdate(notaries);
            realm.commitTransaction();
            RealmConfiguration configuration = realm.getConfiguration();
            realm.close();
            realm = null;
            Realm.compactRealm(configuration);
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Из запроса получаю список объектов которые записываю в БД.

Класс для запроса на сервер:
Java
1
2
3
4
5
6
7
8
9
10
11
12
public class RetrofitRequest {
 
    private static Retrofit retrofit = RetrofitAdapter.getRetrofit();
 
    private static NotaryApi notaryApi =  retrofit.create(NotaryApi.class);
 
    public static Response getNotariesRequest(HashMap<String, String> searchParam) throws IOException {
        Call<Response> call;
        call = notaryApi.getNotaries(searchParam);
        return call.execute().body();
    }
}
Вот такие пироги. Если кто сталкивался с подобным или видит ошибки в реализации сервиса прошу подсказать
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.07.2016, 07:07     Service использует много памяти
Посмотрите здесь:

NDK и С++ кто-нибудь ИЗ ВАС использует? Android
Android GPS service
Android Запуск Activiry из Service
Android SQLite в Service
Android Fragments и service
Service Android
Android App Service
Автозагрузка Service Android
SQLite из Service Android
Кто нибудь использует/использовал эту либу? Android
Работа с Service Android
Android Activity + Service - утечка памяти?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Паблито
2017 / 1759 / 548
Регистрация: 12.05.2014
Сообщений: 6,242
Завершенные тесты: 1
21.07.2016, 10:48     Service использует много памяти #2
в код не вникал, мелочь и врятли сыграет роль, но
Java
1
new SimpleDateFormat("yyyy-MM-dd")
я бы сделал private final static полем класса, а не создавал каждый раз в конструкторе
schlawiner
5 / 5 / 2
Регистрация: 25.05.2014
Сообщений: 21
Завершенные тесты: 1
21.07.2016, 12:39  [ТС]     Service использует много памяти #3
Цитата Сообщение от Паблито Посмотреть сообщение
я бы сделал private final static полем класса
Согласен, для более чистого кода а так не помогло
Yandex
Объявления
21.07.2016, 12:39     Service использует много памяти
Ответ Создать тему
Опции темы

Текущее время: 11:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru