SlideShare a Scribd company logo
1 of 42
Download to read offline
Андроид
Как написать приложение, которое не
              тормозит

       Максим Ушаков, Google
Обзор

 Руки прочь от UI Thread!
 Немного об SQLite
 Память и GC:
   Нативная куча
   Строки/массивы/массивы объектов
   Страшные сказки на ночь
 Как разобраться с памятью?
 Что делать, если всё-таки виноват CPU?
Руки прочь от UI Thread!
"ANR" получает программа, которая

 за 5 секунд не ответила на действие
 пользователя
 или за 10 секунд не закончился
 BroadcastReceiver

Но даже раньше этого пользователи
жалуются, что программа "тормозит"
"ANR" обычно получает тот, кто

  Делает какую-то существенную работу,
  Читает или пишет файлы,
  Обращается к сети,
  или просто общается с базой данных

в основном потоке программы
(Main/UI Thread)
Не делайте этого
Что выполняется "медленно"

Очевидные вещи, вроде увеличения всех
чисел в базе данных на 1, взлома шифра
RSA, и т.д.
Но и менее очевидные:
  Запись на флеш: 5-200(!)мс
  Сеть: пинг = 100мс--10с--больше (GPRS)
  Соединение+HTTP+6k = 1-6с (3G)
  Garbage collector run -- ?мс
Как отложить работу на потом

 android.os.AsyncTask
 android.app.IntentService
 подробнее:
 http://developer.android.com/reference
Как показать это пользователю

 Пользователь нажал на кнопку, вы
 запустили какое-то действие
 Вы не знаете, сколько оно продлится
 Советы бывалых:
   Сразу же выключите кнопку (disable)
   Запустите действие и таймер
   Если действие не завершилось за
   200-500мс, включите progress bar или
   какую-нибудь ещё анимацию
А в моей программе всё ок?

Android 2.3 (Gingerbread): StrictMode

  Следит за вашей программой
  Определяет, где вы делаете опасные
  вызовы в основном потоке
  И наказывает вас!
А в моей программе всё ок?

Вставьте что-то вроде этого в начало
программы:

StrictMode.setThreadPolicy(
   new StrictMode.ThreadPolicy.Builder()
     .detectAll()
     .penaltyLog()
     .build());

И вы получите кучу сообщений в log со
стеком и рассказом, как вы неправы.
SQLite

 Транзакция обязательно пишет журнал
   новый файл, запись, удалить файл
   если места мало, скорость падает
   катастрофически (с 5мс до 60мс)
 Индексы
 EXPLAIN, EXPLAIN QUERY PLAN
 sqlite-wrapper.pl (by bradfitz)
   http://code.google.com/p/zippy-android
А нужен ли SQLite?

 Пишете лог? Лучше добавлять строчки в
 файл
 Только читаете? Нужна простая структура?
 Подумайте, не обойтись ли простой
 структурой в файле
 SQLite -- не Oracle, он всё делает
 прямолинейно
GC/использование памяти

for (Element el: elements) {
  Wrapper wrapper = new Wrapper(el);
  wrapper.doTask();
  // wrapper is deleted
}

Wrapper wrapper = new Wrapper();
for (Element el: elements) {
  wrapper.setElement(el);
  wrapper.doTask();
  // GC is happy!
}
Использование памяти

 16Мб на процесс (24Мб на N1/Desire)
 Это включает себя "нативную кучу", где
 хранятся Bitmap
 Если памяти остаётся мало, GC начинает
 включаться чаще
 Если пытаться занять больше, получите
 OOME
Нативная куча

Bitmap bitmap = ...(1024x768 pixels, 24bpp);

Проблема: с точки зрения GC объект bitmap
занимает ~15байт, поэтому, когда мало
памяти, его удалять нет особого смысла.

Однако: bitmap отъедает 2.3Мб от тех 24Мб,
которые выделены процессу
Нативная куча

Поэтому не полагайтесь на GC:

Bitmap bitmap = ...(1024x768, 24bpp);
... use it ...
... when you don't need it any more:
bitmap.recycle();
Сказки у камина (aka joys of no JIT)

class Item {
  private int x, y;
  public int getX() { return x; }
  public int getY() { return y; }
}
List<Item> array = new ArrayList<Item>(10^9);

Это
  создаёт огромное множество объектов Item
  на куче
  с оверхедом в два раза
Сказки у камина (aka joys of no JIT)
Сказки у камина (aka joys of no JIT)

Обращение к элементу происходит так:
array.get(55).getX()

1. Находим в объекте array виртуальную
   таблицу, соответствующую интерфейсу List
2. Отыскиваем ней метод get
3. Вызываем его
4. Он проверяет границы...
Сказки у камина (aka joys of no JIT)

array.get(55).getX()


5. Находит 55-ый элемент массива
6. В таблице виртуальных методов Item ищет
   getX()
7. Метод getX() прибавляет смещение к
   началу объекта, и...
8. Возвращает нам x!
Сказки у камина (aka joys of no JIT)

class ItemArray {
 private int[] xx;
 private int[] yy;

    public final int getX(int idx) {...}
    public final int getY(int idx) {...}
}

       Нет оверхеда по памяти
      Вызов гораздо быстрее (одно обращение к
      массиву с проверкой границ)
Сказки у камина (aka joys of no JIT)

class ItemArray {
 private int[] xx;
 private int[] yy;

    public final int getX(int idx) {...}
    public final int getY(int idx) {...}
}

       Компилятор может подставлять прямой
      вызов или даже inline из-за final
Сказки у камина (aka joys of no JIT)

  Как прочесть строку из файла в String?
  В файле живут char'ы
  Есть StringBuilder (прочли что-то --
  добавили)
  Дальше -- builder.toString()
  Но тут происходит копирование
  4Mb в файле (== 4Mchar) -->
  --> 8Mb в памяти (char==2bytes) -->
  --> 16Mb при копировании -->
  --> OOME!!!
Сказки у камина (aka joys of no JIT)

  Кроме этого, нельзя без копирования
  перевести из char[] в String и обратно (хотя
  String состоит всего лишь из char[]!)
  Взятие подстроки всегда копирует
  Парсинг любых текстовых форматов
  становится сущим мучением
  (Don't even think of using XML for your next
  project!)
  (Впрочем, если вы реализуете парсинг в
  нативном коде...)
Сказки у камина (aka joys of no JIT)

  В запущенных случаях хочется все строки
  выкинуть и заменить на один большой char
  [] со смещениями
  Немедленно все проблемы решаются --
  можно делать slice, доступ быстрый
  (никаких там виртуальных функций)
  Даже проверка границ в x[i] происходит в
  нативном коде, а не в интерпретируемом!
Использование памяти

 Профайлер памяти:
 http://www.eclipse.org/mat/
 В нужный момент сбросить кучу на диск:
 Debug.dumpHprofData
  ("/data/data/<package>/dump.hprof");
 Далее:
 adb pull /data/data/<package>/dump.hprof
 hprof_conv dump.hprof dump-conv.hprof
 Всё, можно загружать в Eclipse!
Если всё же виноват CPU

 Нет, вы этого так просто знать не можете!
 Сначала запустите профайлер
 Потом найдите виновника...
 ...и перепишите его на C++
Android NDK

http://developer.android.com/sdk/ndk/index.html

  Объявляете фукнции в java как native
  Обрабатываете java-файл:
  javah -jni org.some.package.MyClass
  Получаете .h-файл
  Пишете реализацию функций
Если функции общаются с
примитивными типами, больше
    знать ничего не надо
           (почти)
NDK

 Парсинг текстовых форматов
 И не текстовых тоже
 Тяжёлые вычисления
   Mercator java -> native -> table
 Всё, про что профайлер говорит, что оно
 занимает слишком много времени
 Поиск подстроки в длинной строке,
 например (std->КМП = 0.8, std->native=0.1)
Что почитать
Ссылки

   http://source.android.com/
 (очень полезное чтение, кладезь знаний)
 (и горестных мыслей)
 http://developer.android.com/guide/index.html
 (много рассказов, "как надо")
 http://java.sun.com/developer/onlineTraining/
 Programming/JDCBook/jni.html (JNI)
 http://android-developers.blogspot.com/
 (несколько важных статей про разные
 тонкости)
Спасибо!
теперь спрашивайте
backup slides
Страшные сказки

while(true) {
  Task task = queue.getTaskBlocking();
  task.execute();
}
Страшные сказки

Task task;
while(true) {
  task = queue.getTaskBlocking();
  task.execute();
}
Страшные сказки

while(true) {
  Task task = queue.getTaskBlocking();
  task.execute();
  task = null;
}
Страшные сказки

while(true) {
  Task task = queue.getTaskBlocking();
  task.execute();
}
Совсем Страшные сказки

class Magic {
  static private int n = 0;
  static public void doMagic(Object obj) {
    if (obj != null) n++;
  }
  static public int getMagic() { return n; }
}
Совсем Страшные сказки

class Magic {
  static private int n = 0;
  static public void doMagic(Object obj) {
    if (obj != null) n++;
  }
  static public int getMagic() { return n; }
}
while(true) {
  Task task = queue.getTaskBlocking();
  task.execute();
  task = null;
  Magic.doMagic(task);
}
Уфф...

мурашки по спине

More Related Content

What's hot

#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6Nikolay Samokhvalov
 
Вячеслав Бахмутов
Вячеслав БахмутовВячеслав Бахмутов
Вячеслав БахмутовCodeFest
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Ontico
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)Ontico
 
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)Badoo Development
 
Database First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДDatabase First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДNikolay Samokhvalov
 
Flask как хорошее решение для веб проекта
Flask как хорошее решение для веб проектаFlask как хорошее решение для веб проекта
Flask как хорошее решение для веб проектаPython Meetup
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaAndrei Pangin
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Tanya Denisyuk
 
Technopolis.NoSQL 03 Cassandra
Technopolis.NoSQL 03 CassandraTechnopolis.NoSQL 03 Cassandra
Technopolis.NoSQL 03 CassandraVadim Tsesko
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуcorehard_by
 
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)Ontico
 
04 net saturday eugene sukhikh ''the basic performance questions''
04 net saturday eugene sukhikh ''the basic performance questions''04 net saturday eugene sukhikh ''the basic performance questions''
04 net saturday eugene sukhikh ''the basic performance questions''DneprCiklumEvents
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
 
Практическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.ПочтеПрактическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.ПочтеAlexey Androsov
 
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)Ontico
 

What's hot (19)

#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
 
Вячеслав Бахмутов
Вячеслав БахмутовВячеслав Бахмутов
Вячеслав Бахмутов
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
 
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
 
Cassandra
CassandraCassandra
Cassandra
 
Database First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДDatabase First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБД
 
Flask как хорошее решение для веб проекта
Flask как хорошее решение для веб проектаFlask как хорошее решение для веб проекта
Flask как хорошее решение для веб проекта
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in Java
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
 
Technopolis.NoSQL 03 Cassandra
Technopolis.NoSQL 03 CassandraTechnopolis.NoSQL 03 Cassandra
Technopolis.NoSQL 03 Cassandra
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почему
 
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)
Highload на GPU, опыт Vinci / Олег Илларионов (ВКонтакте)
 
04 net saturday eugene sukhikh ''the basic performance questions''
04 net saturday eugene sukhikh ''the basic performance questions''04 net saturday eugene sukhikh ''the basic performance questions''
04 net saturday eugene sukhikh ''the basic performance questions''
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
 
Практическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.ПочтеПрактическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.Почте
 
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)
Язык Lua — секреты производительности / Ник Заварицкий (Mail.ru)
 

Similar to Android: Как написать приложение, которое не тормозит

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonovComputer Science Club
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularizationIvan Krylov
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Andrew Mayorov
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage CollectorOlexandra Dmytrenko
 
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется всеОмские ИТ-субботники
 
Web20 from zero
Web20 from zeroWeb20 from zero
Web20 from zeroqweasdrty
 
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)Ontico
 
sphinx Hlpp2008
sphinx Hlpp2008sphinx Hlpp2008
sphinx Hlpp2008Ontico
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9Technopark
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...Nikolay Samokhvalov
 
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"Yandex
 
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...Ontico
 
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Ontico
 
Лекция 6
Лекция 6Лекция 6
Лекция 6itc73
 
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017Alex Chistyakov
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструментыRoman Dvornov
 

Similar to Android: Как написать приложение, которое не тормозит (20)

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularization
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
 
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
 
Web20 from zero
Web20 from zeroWeb20 from zero
Web20 from zero
 
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
Практическое создание крупного масштабируемого web 2.0 c нуля (Дмитрий Бородин)
 
sphinx Hlpp2008
sphinx Hlpp2008sphinx Hlpp2008
sphinx Hlpp2008
 
php frameworks
php frameworksphp frameworks
php frameworks
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9
 
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва... Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
 
PowerShell
PowerShellPowerShell
PowerShell
 
Java 9 - кратко о новом
Java 9 -  кратко о новомJava 9 -  кратко о новом
Java 9 - кратко о новом
 
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
 
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
 
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
 
Лекция 6
Лекция 6Лекция 6
Лекция 6
 
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 

More from Elena Kotina

Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...
Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...
Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...Elena Kotina
 
PJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаPJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаElena Kotina
 
PJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаPJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаElena Kotina
 
Мобильные платформы и изменение пользовательского опыта
Мобильные платформы и изменение пользовательского опытаМобильные платформы и изменение пользовательского опыта
Мобильные платформы и изменение пользовательского опытаElena Kotina
 
Pay-Mobile API: платежи банковскими картами в мобильном
Pay-Mobile API: платежи банковскими картами в мобильномPay-Mobile API: платежи банковскими картами в мобильном
Pay-Mobile API: платежи банковскими картами в мобильномElena Kotina
 
Платформа "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...
Платформа  "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...Платформа  "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...
Платформа "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...Elena Kotina
 
Продвижение мобильных приложений в мобильном интернете
Продвижение мобильных приложений в мобильном интернетеПродвижение мобильных приложений в мобильном интернете
Продвижение мобильных приложений в мобильном интернетеElena Kotina
 
Рынок мобильных приложений: альтернативные методы монетизации
Рынок мобильных приложений: альтернативные методы монетизацииРынок мобильных приложений: альтернативные методы монетизации
Рынок мобильных приложений: альтернативные методы монетизацииElena Kotina
 
Мобильный интернет – кто здесь?!
Мобильный интернет – кто здесь?!Мобильный интернет – кто здесь?!
Мобильный интернет – кто здесь?!Elena Kotina
 
Практический кейс: "Назначение нового менеджера в команду"
Практический кейс: "Назначение нового менеджера в команду"Практический кейс: "Назначение нового менеджера в команду"
Практический кейс: "Назначение нового менеджера в команду"Elena Kotina
 
Nokia для разработчиков
Nokia для разработчиковNokia для разработчиков
Nokia для разработчиковElena Kotina
 
MeeGo, AppUp & Atom – планы и перспективы
MeeGo, AppUp & Atom – планы и перспективыMeeGo, AppUp & Atom – планы и перспективы
MeeGo, AppUp & Atom – планы и перспективыElena Kotina
 
А теперь мы идем к вам! Реклама в мобильных приложениях
А теперь мы идем к вам! Реклама в мобильных приложенияхА теперь мы идем к вам! Реклама в мобильных приложениях
А теперь мы идем к вам! Реклама в мобильных приложенияхElena Kotina
 
mail.ru: Технологические инновации и лучшие люди
mail.ru: Технологические инновации и лучшие людиmail.ru: Технологические инновации и лучшие люди
mail.ru: Технологические инновации и лучшие людиElena Kotina
 
Разработка кроссплатформенного приложения с использованием Airplay SDK
Разработка кроссплатформенного приложения с использованием Airplay SDKРазработка кроссплатформенного приложения с использованием Airplay SDK
Разработка кроссплатформенного приложения с использованием Airplay SDKElena Kotina
 
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...Elena Kotina
 
Мобильный маркетинг и реклама как интегратор медиамикса
Мобильный маркетинг и реклама как интегратор медиамиксаМобильный маркетинг и реклама как интегратор медиамикса
Мобильный маркетинг и реклама как интегратор медиамиксаElena Kotina
 
Мобильные приложения и корпоративные сайты. Технологии взаимодействия
Мобильные приложения и корпоративные сайты. Технологии взаимодействияМобильные приложения и корпоративные сайты. Технологии взаимодействия
Мобильные приложения и корпоративные сайты. Технологии взаимодействияElena Kotina
 
Использование геосерсисов для монетизации мобильных приложений
Использование геосерсисов для монетизации мобильных приложенийИспользование геосерсисов для монетизации мобильных приложений
Использование геосерсисов для монетизации мобильных приложенийElena Kotina
 
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...Elena Kotina
 

More from Elena Kotina (20)

Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...
Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...
Возможности, применение и монетизация социальных API Mail.Ru на мобильных пла...
 
PJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаPJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проекта
 
PJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проектаPJSIP – VOIP движок, как база проекта
PJSIP – VOIP движок, как база проекта
 
Мобильные платформы и изменение пользовательского опыта
Мобильные платформы и изменение пользовательского опытаМобильные платформы и изменение пользовательского опыта
Мобильные платформы и изменение пользовательского опыта
 
Pay-Mobile API: платежи банковскими картами в мобильном
Pay-Mobile API: платежи банковскими картами в мобильномPay-Mobile API: платежи банковскими картами в мобильном
Pay-Mobile API: платежи банковскими картами в мобильном
 
Платформа "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...
Платформа  "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...Платформа  "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...
Платформа "Агент+ 2.0" - возможности для быстрой разработки мобильных бизнес...
 
Продвижение мобильных приложений в мобильном интернете
Продвижение мобильных приложений в мобильном интернетеПродвижение мобильных приложений в мобильном интернете
Продвижение мобильных приложений в мобильном интернете
 
Рынок мобильных приложений: альтернативные методы монетизации
Рынок мобильных приложений: альтернативные методы монетизацииРынок мобильных приложений: альтернативные методы монетизации
Рынок мобильных приложений: альтернативные методы монетизации
 
Мобильный интернет – кто здесь?!
Мобильный интернет – кто здесь?!Мобильный интернет – кто здесь?!
Мобильный интернет – кто здесь?!
 
Практический кейс: "Назначение нового менеджера в команду"
Практический кейс: "Назначение нового менеджера в команду"Практический кейс: "Назначение нового менеджера в команду"
Практический кейс: "Назначение нового менеджера в команду"
 
Nokia для разработчиков
Nokia для разработчиковNokia для разработчиков
Nokia для разработчиков
 
MeeGo, AppUp & Atom – планы и перспективы
MeeGo, AppUp & Atom – планы и перспективыMeeGo, AppUp & Atom – планы и перспективы
MeeGo, AppUp & Atom – планы и перспективы
 
А теперь мы идем к вам! Реклама в мобильных приложениях
А теперь мы идем к вам! Реклама в мобильных приложенияхА теперь мы идем к вам! Реклама в мобильных приложениях
А теперь мы идем к вам! Реклама в мобильных приложениях
 
mail.ru: Технологические инновации и лучшие люди
mail.ru: Технологические инновации и лучшие людиmail.ru: Технологические инновации и лучшие люди
mail.ru: Технологические инновации и лучшие люди
 
Разработка кроссплатформенного приложения с использованием Airplay SDK
Разработка кроссплатформенного приложения с использованием Airplay SDKРазработка кроссплатформенного приложения с использованием Airplay SDK
Разработка кроссплатформенного приложения с использованием Airplay SDK
 
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...
Пробки DorogaTV для мобильных приложений. Как встроить пробки в Ваше мобильно...
 
Мобильный маркетинг и реклама как интегратор медиамикса
Мобильный маркетинг и реклама как интегратор медиамиксаМобильный маркетинг и реклама как интегратор медиамикса
Мобильный маркетинг и реклама как интегратор медиамикса
 
Мобильные приложения и корпоративные сайты. Технологии взаимодействия
Мобильные приложения и корпоративные сайты. Технологии взаимодействияМобильные приложения и корпоративные сайты. Технологии взаимодействия
Мобильные приложения и корпоративные сайты. Технологии взаимодействия
 
Использование геосерсисов для монетизации мобильных приложений
Использование геосерсисов для монетизации мобильных приложенийИспользование геосерсисов для монетизации мобильных приложений
Использование геосерсисов для монетизации мобильных приложений
 
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...
Новые возможности информационных агентств и СМИ на примере iPhone, iPad и дру...
 

Android: Как написать приложение, которое не тормозит

  • 1. Андроид Как написать приложение, которое не тормозит Максим Ушаков, Google
  • 2. Обзор Руки прочь от UI Thread! Немного об SQLite Память и GC: Нативная куча Строки/массивы/массивы объектов Страшные сказки на ночь Как разобраться с памятью? Что делать, если всё-таки виноват CPU?
  • 4. "ANR" получает программа, которая за 5 секунд не ответила на действие пользователя или за 10 секунд не закончился BroadcastReceiver Но даже раньше этого пользователи жалуются, что программа "тормозит"
  • 5. "ANR" обычно получает тот, кто Делает какую-то существенную работу, Читает или пишет файлы, Обращается к сети, или просто общается с базой данных в основном потоке программы (Main/UI Thread)
  • 7. Что выполняется "медленно" Очевидные вещи, вроде увеличения всех чисел в базе данных на 1, взлома шифра RSA, и т.д. Но и менее очевидные: Запись на флеш: 5-200(!)мс Сеть: пинг = 100мс--10с--больше (GPRS) Соединение+HTTP+6k = 1-6с (3G) Garbage collector run -- ?мс
  • 8. Как отложить работу на потом android.os.AsyncTask android.app.IntentService подробнее: http://developer.android.com/reference
  • 9. Как показать это пользователю Пользователь нажал на кнопку, вы запустили какое-то действие Вы не знаете, сколько оно продлится Советы бывалых: Сразу же выключите кнопку (disable) Запустите действие и таймер Если действие не завершилось за 200-500мс, включите progress bar или какую-нибудь ещё анимацию
  • 10. А в моей программе всё ок? Android 2.3 (Gingerbread): StrictMode Следит за вашей программой Определяет, где вы делаете опасные вызовы в основном потоке И наказывает вас!
  • 11. А в моей программе всё ок? Вставьте что-то вроде этого в начало программы: StrictMode.setThreadPolicy( new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build()); И вы получите кучу сообщений в log со стеком и рассказом, как вы неправы.
  • 12. SQLite Транзакция обязательно пишет журнал новый файл, запись, удалить файл если места мало, скорость падает катастрофически (с 5мс до 60мс) Индексы EXPLAIN, EXPLAIN QUERY PLAN sqlite-wrapper.pl (by bradfitz) http://code.google.com/p/zippy-android
  • 13. А нужен ли SQLite? Пишете лог? Лучше добавлять строчки в файл Только читаете? Нужна простая структура? Подумайте, не обойтись ли простой структурой в файле SQLite -- не Oracle, он всё делает прямолинейно
  • 14. GC/использование памяти for (Element el: elements) { Wrapper wrapper = new Wrapper(el); wrapper.doTask(); // wrapper is deleted } Wrapper wrapper = new Wrapper(); for (Element el: elements) { wrapper.setElement(el); wrapper.doTask(); // GC is happy! }
  • 15. Использование памяти 16Мб на процесс (24Мб на N1/Desire) Это включает себя "нативную кучу", где хранятся Bitmap Если памяти остаётся мало, GC начинает включаться чаще Если пытаться занять больше, получите OOME
  • 16. Нативная куча Bitmap bitmap = ...(1024x768 pixels, 24bpp); Проблема: с точки зрения GC объект bitmap занимает ~15байт, поэтому, когда мало памяти, его удалять нет особого смысла. Однако: bitmap отъедает 2.3Мб от тех 24Мб, которые выделены процессу
  • 17. Нативная куча Поэтому не полагайтесь на GC: Bitmap bitmap = ...(1024x768, 24bpp); ... use it ... ... when you don't need it any more: bitmap.recycle();
  • 18. Сказки у камина (aka joys of no JIT) class Item { private int x, y; public int getX() { return x; } public int getY() { return y; } } List<Item> array = new ArrayList<Item>(10^9); Это создаёт огромное множество объектов Item на куче с оверхедом в два раза
  • 19. Сказки у камина (aka joys of no JIT)
  • 20. Сказки у камина (aka joys of no JIT) Обращение к элементу происходит так: array.get(55).getX() 1. Находим в объекте array виртуальную таблицу, соответствующую интерфейсу List 2. Отыскиваем ней метод get 3. Вызываем его 4. Он проверяет границы...
  • 21. Сказки у камина (aka joys of no JIT) array.get(55).getX() 5. Находит 55-ый элемент массива 6. В таблице виртуальных методов Item ищет getX() 7. Метод getX() прибавляет смещение к началу объекта, и... 8. Возвращает нам x!
  • 22. Сказки у камина (aka joys of no JIT) class ItemArray { private int[] xx; private int[] yy; public final int getX(int idx) {...} public final int getY(int idx) {...} } Нет оверхеда по памяти Вызов гораздо быстрее (одно обращение к массиву с проверкой границ)
  • 23. Сказки у камина (aka joys of no JIT) class ItemArray { private int[] xx; private int[] yy; public final int getX(int idx) {...} public final int getY(int idx) {...} } Компилятор может подставлять прямой вызов или даже inline из-за final
  • 24. Сказки у камина (aka joys of no JIT) Как прочесть строку из файла в String? В файле живут char'ы Есть StringBuilder (прочли что-то -- добавили) Дальше -- builder.toString() Но тут происходит копирование 4Mb в файле (== 4Mchar) --> --> 8Mb в памяти (char==2bytes) --> --> 16Mb при копировании --> --> OOME!!!
  • 25. Сказки у камина (aka joys of no JIT) Кроме этого, нельзя без копирования перевести из char[] в String и обратно (хотя String состоит всего лишь из char[]!) Взятие подстроки всегда копирует Парсинг любых текстовых форматов становится сущим мучением (Don't even think of using XML for your next project!) (Впрочем, если вы реализуете парсинг в нативном коде...)
  • 26. Сказки у камина (aka joys of no JIT) В запущенных случаях хочется все строки выкинуть и заменить на один большой char [] со смещениями Немедленно все проблемы решаются -- можно делать slice, доступ быстрый (никаких там виртуальных функций) Даже проверка границ в x[i] происходит в нативном коде, а не в интерпретируемом!
  • 27. Использование памяти Профайлер памяти: http://www.eclipse.org/mat/ В нужный момент сбросить кучу на диск: Debug.dumpHprofData ("/data/data/<package>/dump.hprof"); Далее: adb pull /data/data/<package>/dump.hprof hprof_conv dump.hprof dump-conv.hprof Всё, можно загружать в Eclipse!
  • 28. Если всё же виноват CPU Нет, вы этого так просто знать не можете! Сначала запустите профайлер Потом найдите виновника... ...и перепишите его на C++
  • 29. Android NDK http://developer.android.com/sdk/ndk/index.html Объявляете фукнции в java как native Обрабатываете java-файл: javah -jni org.some.package.MyClass Получаете .h-файл Пишете реализацию функций
  • 30. Если функции общаются с примитивными типами, больше знать ничего не надо (почти)
  • 31. NDK Парсинг текстовых форматов И не текстовых тоже Тяжёлые вычисления Mercator java -> native -> table Всё, про что профайлер говорит, что оно занимает слишком много времени Поиск подстроки в длинной строке, например (std->КМП = 0.8, std->native=0.1)
  • 33. Ссылки http://source.android.com/ (очень полезное чтение, кладезь знаний) (и горестных мыслей) http://developer.android.com/guide/index.html (много рассказов, "как надо") http://java.sun.com/developer/onlineTraining/ Programming/JDCBook/jni.html (JNI) http://android-developers.blogspot.com/ (несколько важных статей про разные тонкости)
  • 36. Страшные сказки while(true) { Task task = queue.getTaskBlocking(); task.execute(); }
  • 37. Страшные сказки Task task; while(true) { task = queue.getTaskBlocking(); task.execute(); }
  • 38. Страшные сказки while(true) { Task task = queue.getTaskBlocking(); task.execute(); task = null; }
  • 39. Страшные сказки while(true) { Task task = queue.getTaskBlocking(); task.execute(); }
  • 40. Совсем Страшные сказки class Magic { static private int n = 0; static public void doMagic(Object obj) { if (obj != null) n++; } static public int getMagic() { return n; } }
  • 41. Совсем Страшные сказки class Magic { static private int n = 0; static public void doMagic(Object obj) { if (obj != null) n++; } static public int getMagic() { return n; } } while(true) { Task task = queue.getTaskBlocking(); task.execute(); task = null; Magic.doMagic(task); }