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

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

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

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

21.07.2016, 07:07. Просмотров 202. Ответов 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();
    }
}
Вот такие пироги. Если кто сталкивался с подобным или видит ошибки в реализации сервиса прошу подсказать
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.07.2016, 07:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Service использует много памяти (Программирование Android):

Activity + Service - утечка памяти? - Программирование Android
Всем привет. Подскажите, пожалуйста, когда я запускаю сервис из активити (startService) и мой сервис работает достаточно долго, так...

NDK и С++ кто-нибудь ИЗ ВАС использует? - Программирование Android
Отзовитесь! Хочу услышать мнение о сложностях от тех кто реально использует NDK (c++). Теорию изучаю уже давно - знаю все плюсы и минусы...

Кто нибудь использует/использовал эту либу? - Программирование Android
'com.squareup.okhttp:okhttp:2.6.0' OkHttpClient Пользуетесь ли вы этой библиотекой?

Service - Программирование Android
Как создать приложение как Service?

App Service - Программирование Android
Возможно ли как-то создать приложение, которое запускает сервис и при этом, если в дальнейшем удалить само приложение, то сервис останется...

GPS service - Программирование Android
Написал сервис для работы GPS однако при попытке вытащить данные просто выдаёт 0 класс реализующий работу c GPS: package...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Pablito
2487 / 1932 / 604
Регистрация: 12.05.2014
Сообщений: 6,793
Завершенные тесты: 1
21.07.2016, 10:48 #2
в код не вникал, мелочь и врятли сыграет роль, но
Java
1
new SimpleDateFormat("yyyy-MM-dd")
я бы сделал private final static полем класса, а не создавал каждый раз в конструкторе
1
schlawiner
5 / 5 / 2
Регистрация: 25.05.2014
Сообщений: 23
Завершенные тесты: 1
21.07.2016, 12:39  [ТС] #3
Цитата Сообщение от Паблито Посмотреть сообщение
я бы сделал private final static полем класса
Согласен, для более чистого кода а так не помогло
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2016, 12:39
Привет! Вот еще темы с ответами:

Fragments и service - Программирование Android
такой вопрос как реализовать запуск сервиса и обработку результатов приложении где есть fragments.? хотелось бы запускать сервис в...

Автозагрузка Service - Программирование Android
Привет, люди! Давно бьюсь с автозапуском сервисов. Скиньте, пожалуйста РАБОЧИЙ пример сего действа, иначе я вообще никогда так и не...

Работа с Service - Программирование Android
Всем добрый вечер! Есть приложение под андроид. С активити, с интерфейсом, всё как нужно. Теперь потребовалось сделать из него фоновое...

SQLite из Service - Программирование Android
Здравствуйте, у меня такой вопрос. Уже бьюсь 2 дня, ни как не могу сделать. Может вы мне поможете советом, а лучше примером. Как...


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

Или воспользуйтесь поиском по форуму:
Ответ Создать тему
Опции темы

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