Шрифт:
На рис. 12.1, 12.2, 12.3 и 12.4 проиллюстрированы четыре основных типа потребления памяти.
Рис. 12.1 схематически иллюстрирует поведение приложения в отношении потребления памяти в соответствии с наихудшим сценарием, который характеризуется высоким объемом постоянно распределенной памяти и неэкономным расходованием памяти в процессе работы алгоритмов. В этом случае постоянно распределенная память мобильного приложения занимает почти всю память, имеющуюся в системе. В результате этого в случае непрерывного размещения и уничтожения объектов, осуществляемого неэффективными алгоритмами, в памяти остается совсем мало места. Очень важно не забывать о том, что область памяти, занимаемая объектом, не может быть повторно использована сразу же после уничтожения ссылки на объект; чтобы восстановить память с целью сделать ее доступной для дальнейшего использования, должна быть выполнена операция сборки мусора. Непрерывное размещение и удаление объектов является причиной увеличения крутизны наклона зубьев пилообразного графика потребления памяти. Нехватка места для размещения объектов в памяти делает необходимой ее частую очистку от "мусора", что каждый раз сопровождается дополнительными накладными расходами.
В результате этого производительность резко ухудшается, поскольку сборщик мусора вынужден выполняться практически непрерывно, чтобы приложение могло хоть как-то работать.
Рис. 12.1. Наихудший случай: чрезмерное потребление памяти состоянием приложения, неэкономичные алгоритмы
На рис. 12.2 представлен промежуточный в отношении производительности случай. Хотя этому варианту поведения системы, как и предыдущему, также свойственно неэкономное размещение объектов в памяти алгоритмами приложения, тем не менее, объем постоянно распределенной памяти в этом случае гораздо меньше. Это означает, что, несмотря на то, что наклон линии, отображающей процессы непрерывного размещения и уничтожения объектов, остается крутым, имеется гораздо больше свободного пространства, способного дольше хранить "мусор". Таким образом, необходимость в сборке мусора будет возникать гораздо реже, в результате чего производительность значительно улучшается по сравнению с предыдущим случаем.
Рис. 12.3 иллюстрирует еще одну промежуточную модель управления памятью, обратную той, которая рассматривалась выше. Кривая потребления памяти характеризуется высоким уровнем постоянно распределенной памяти, соответствующей глобальным объектам и системным данным, но рабочая память используется алгоритмами приложения гораздо более эффективным образом. Хотя ее объем и невелик, однако она экономнее расходуется для размещения объектов алгоритмами, что устраняет необходимость в ее непрерывном восстановлении посредством механизма сборки мусора.
На рис 12.4 представлен наиболее оптимальный вариант расходования памяти.
Рис. 12.2. Промежуточный случай: эффективно организованное состояние приложения, неэкономичные алгоритмы
Рис. 12.3. Промежуточный случай: чрезмерное потребление памяти состоянием приложения, экономичные алгоритмы
Рис. 12.4. Наиболее оптимальный случай: эффективное состояние приложения, и экономичные алгоритмы
Количество постоянно хранимых в памяти объектов ограничено, так что алгоритмы получают в свое распоряжение гораздо большее рабочее пространство. При этом временные объекты создаются алгоритмами весьма экономно. В результате этого сборка мусора должна выполняться сравнительно редко, а это означает увеличение производительности приложения и уменьшение вероятности его "зависания".
Создавая свои мобильные приложения, вы должны стремиться к реализации модели использования памяти, которую отражает рис. 12.4. Приложение должно поддерживать информацию о состоянии, обеспечивающую все то, что требуется пользовательским данным, но реализовываться это должно по возможности наиболее эффективным способом. Кроме того, приложение должно сохранять в памяти те ресурсы, которые обычно требуется создавать и уничтожать в процессе устойчивого выполнения вашего приложения.
Хорошая организация управления памятью предполагает достижение баланса множества факторов и эффективное использование памяти, с которой работает приложение. Не имеет смысла стремиться к снижению объема информации о глобальном состоянии до минимума, если приложению для нормального выполнения потребуется постоянно создавать и уничтожать те же самые объекты в виде временных объектов. Точно так же, не стоит хранить в памяти состояние приложения в таком объеме, который приводит к образованию дефицита рабочего пространства, в результате чего эффективное выполнение алгоритмов приложения становится невозможным без непрерывного освобождения памяти посредством механизма сборки мусора. Все, что для этого требуется — это обеспечение разумного компромисса между двумя вышеупомянутыми противоречащими друг другу требованиями.
Производительность и многопоточное выполнение
В качестве общего правила руководствуйтесь тем, что от введения нескольких потоков ваше приложение работать быстрее не станет. Суть еще одного правила состоит в том, что организация управления параллельными потоками выполнения значительно усложнит код вашего приложения и затруднит его понимание, сопровождение и отладку. Поэтому очень важно не поддаваться "очарованию потоками" и не пытаться придумывать для них все новые способы применения в тех случаях, когда они абсолютно не нужны.
В то же время для использования фоновых потоков в приложениях существуют веские причины. Наиболее привлекательной областью применения потоков является сохранение способности вашего мобильного приложения к интерактивному взаимодействию с пользователем в тех случаях, когда выполнение задачи занимает длительное время или же о длительности ее выполнения заранее ничего сказать невозможно. Длительное выполнение характерно для тех задач, которые связаны с интенсивными вычислениями или интенсивной алгоритмической обработкой. Задачи, время выполнения которых является неопределенным, требуют доступа к ресурсам, которыми вы непосредственно управлять не можете. (Так, спрогнозировать длительность задержек в случае доступа к информации через сеть практически невозможно.) Для такого рода операций отличные возможности предоставляет работа в асинхронном режиме.