Программирование мобильных устройств на платформе .NET Compact Framework
Шрифт:
Использование тщательно продуманного управления памятью обеспечивает значительные преимущества как при разработке приложений для настольных компьютеров, так и при разработке приложений для мобильных устройств, однако в последнем случае такой подход должен быть обязательно плановым. Отсутствие продуманного управления памятью в случае приложений для настольных компьютеров приводит к постепенному обрастанию приложения неиспользуемыми объектами и замедлению его работы. В противоположность этому мобильное приложение, работающее без применения выверенных стратегий управления памятью на макроскопическом и микроскопическом уровнях, очень быстро пересекает опасную черту, и его дальнейшее использование становится истинным мучением.
Управление памятью на макроскопическом "уровне приложения"
На рис. 8.1 в схематическом виде отображено, как снижается производительность приложения с увеличением объема используемой памяти.
Рис. 8.1. Изменение
Из поведения графиков видно, что в случае приложений для настольных компьютеров диапазон объемов используемой памяти, при которых производительность остается в допустимых пределах, является намного более широким. При превышении некоторого порогового значения производительность резко снижается, поскольку начинается свопинг данных между памятью и файлом подкачки, а сборщик мусора все чаще пытается освобождать и уплотнять память; вместе с тем, падение производительности происходит гораздо медленнее, чем в случае мобильных устройств. Для мобильных устройств диапазон используемых объемов памяти, при которых производительность остается на приемлемом уровне, оказывается более узким. При превышении некоторого порогового значения наблюдается резкое падение производительности мобильного приложения, поскольку сборщик мусора работает почти непрерывно, пытаясь высвободить все большие объемы памяти. На графиках отмечены участки, соответствующие использованию объемов памяти, при которых приложение еще способно нормально функционировать. Коль скоро потребление памяти не превышает некоторого критического значения, ничего особенного в целом не происходит. Однако при пересечении критической точки производительность приложения резко падает, поскольку сборщик мусора вынужден работать все чаще, изо всех сил пытаясь высвободить память для нужд приложения.
В отличие от сред выполнения управляемого кода (.NET Compact Framework, Java и так далее), при разработке приложений в собственных кодах сборка мусора не используется. Однако это вовсе не означает, что в этом случае вам удается соскочить с крючка; напротив — нагрузка на стадии проектирования, вероятнее всего, только увеличится! При выполнении на настольных компьютерах приложения, основанные на собственных кодах, пользуются всеми преимуществами, которые неявно предоставляет операционная система, осуществляя обмен страницами ОЗУ с дисковым файлом подкачки. В результате этого, хотя выполнение приложения и может замедляться, оно при любых условиях сохраняет свою работоспособность. Если же ваше мобильное приложение превысит допустимые пределы расхода памяти, то оно просто-напросто исчерпает все ее резервы и завершится сбоем. Отсюда следует, что при разработке мобильных приложений, основанных на собственных кодах, разработчик должен заранее предпринять меры, позволяющие избежать возникновения подобных ситуаций. Кроме того, алгоритмы на основе собственного кода, которые без особой на то необходимости распределяют и освобождают память лишь потому, что были неудачно спроектированы, будут вынуждены бороться с проблемами фрагментации памяти, что также приведет к снижению производительности. В то время как среды времени выполнения управляемого кода могут справляться с фрагментацией памяти за счет ее уплотнения в процессе сборки мусора, в случае собственных кодов аналогичные встроенные возможности отсутствуют. А это означает, что вы должны сами продумать детальную схему управления памятью и самостоятельно ее реализовать.
Перед вами, как перед проектировщиком мобильного приложения, не стоит задача найти способы, позволяющие использовать всю свободную память вплоть до некоторой пороговой величины, при превышении которой производительность начинает резко ухудшаться. Вместо этого вы должны стремиться к тому, чтобы у вас всегда оставался некоторый резервный запас свободной памяти (резерв безопасности), оставляющий простор для маневров, что будет гарантией эффективного выполнения вашего приложения в самых различных ситуациях. Необходимость такого подхода диктуется тем, что в типичных условиях ваше приложение не имеет возможности полностью контролировать всю установленную на устройстве память; память находится в совместном распоряжении операционной системы и всех приложений, которые могут одновременно выполняться пользователем. Если какое-то приложение распределяет и удерживает лишние объемы памяти, то от этого будет страдать производительность всех приложений. Не занимайте больше памяти, нежели требуется, и освобождайте те ее излишки, непосредственная необходимость в которых отпала
Как и в случае других аспектов проектирования мобильных приложений, разработка удачной модели памяти, удовлетворяющей всем вашим требованиям, возможна лишь в результате проведения экспериментов и при наличии опыта. Вы должны экспериментально проверить самые различные подходы, и довести характеристики модели до нужных, исходя из доступных ресурсов мобильного устройства и требований приложения. Залогом успешной разработки мобильных приложений является творческий подход к решению проблем, открывающий широкий простор для экспериментов.
Добавочная память стоит денег, увеличивает тепловыделение, потребляет электроэнергию и занимает в устройстве дополнительное место. Со временем ситуация в отношении каждого из этих факторов будет только улучшаться, но с ними всегда надо будет считаться. В соответствии с законом Мура, согласно
Большинство современных мобильных устройств уже располагают вполне приличными объемами памяти, обеспечивающими решение широкого круга задач, но этой памятью необходимо распоряжаться благоразумно. Очень часто плохие привычки, приобретенные в процессе проектирования приложений для настольных компьютеров, переносятся и на работу с мобильными устройствами. Это приводит к отсутствию строгого подхода к распределению памяти в алгоритмах и неэффективному управлению памятью, допускающему хранение в памяти ресурсов, которые больше не используются.
Ранее в этой книге мы уже использовали аналогию, в которой позволили себе сравнить современные настольные компьютеры с большими особняками в сельской местности, а мобильные устройства — с шикарно выглядящими, но небольшими городскими квартирами. Очень важно, чтобы вы никогда не забывали об этом образном примере, иллюстрирующем суть "размерных ограничений". Вы можете реализовать на мобильном устройстве почти все, что хотите, но вам не удастся сделать это сразу или немедленно завладеть всей памятью. Вы должны располагать набором определенных правил, регламентирующих то, какие вещи должны находиться в квартире, а какие должны быть вынесены из нее.
Последующие поколения мобильных устройств будут гораздо мощнее, и будут располагать большими объемами памяти, но от них все равно будет требоваться еще большее. Продуманные стратегии управления памятью будут по-прежнему оставаться ключевым фактором создания отличных мобильных приложений.
Хранить в памяти неиспользуемые объекты слишком расточительно, поскольку они занимают место, которое можно было бы использовать с большей эффективностью для активных составляющих вашего приложения. С другой стороны, было бы слишком легкомысленно освобождать память от объектов сразу же после того, как непосредственная необходимость в них исчезла.
Обратимся к метафоре. Предположим, что вы живете в небольшой квартире и для скрепления бумажных листов вам потребовался скоросшиватель, который вы должны купить, сходив для этого в магазин. Это займет у вас время и ресурсы — не очень много, но вполне достаточно, чтобы вы это ощутили. Выбросив скоросшиватель сразу же после того, как он будет использован, вы освободите в квартире немного места (фактически это произойдет лишь после того, как вы избавитесь от мусора в ведре, в которое выбросили скоросшиватель), но останетесь без скоросшивателя. Если впоследствии вам вновь понадобится что-либо скрепить, вы должны будете опять потратить время на посещение магазина и понести расходы, покупая новый скоросшиватель. Если бы все происходило именно так, то ваши действия следовало бы рассматривать как опрометчивые; зная, что на протяжении ближайшего года-двух скоросшиватель вам вновь может понадобиться, его лучше было бы держать где-то поблизости. Однако если вы абсолютно уверены в том, что необходимость в скоросшивателе повторно никогда не возникнет (возможно, с этого момента вы решили пользоваться только зажимами), то вы должны выбросить его, как бы мало места он ни занимал. Кому охота загромождать квартиру бесполезными вещами?
Во всем должен существовать определенный баланс, который вам предстоит определить. Поскольку скоросшиватель — вещь довольно полезная, по своим размерам не очень габаритная и время от времени может использоваться, то его следует оставить под рукой. А что можно сказать по поводу большого парового пылесоса для чистки ковров? Опять-таки, вы могли бы сходить в магазин, купить пылесос, затратив на это значительные денежные и временные ресурсы, и держать его где-то в квартире; в то же время, если вы живете в небольшой квартирке и чистите свои ковры сравнительно редко, то такое решение было бы не самым разумным. Вместо этого вам следовало бы взять пылесос напрокат, сделать все, что надо, а затем отнести его обратно в пункт проката. Вы всегда должны планировать, какие вещи лучше держать при себе, а от каких лучше избавляться, когда они сделали свое дело.
Сложнее всего принимать решения относительно объектов, которые попадают в промежуточную категорию. Сами по себе эти объекты не отличаются большими размерами или высокой стоимостью, каждый из них занимает сравнительно немного места и они могут оказаться потенциально полезными в не столь отдаленном будущем. Эти объекты можно уподобить одежде, которую вы почти никогда не носите. Ее можно было бы и выбросить, но также неплохо оставить у себя на тот случай, если вы измените свое мнение. Если такие объекты немногочисленны, то держать их поблизости не составляет труда, но в эту категорию попадает так много объектов, что легко заполнить ими все имеющиеся помещения, что не оставит вам места для тех вещей, которыми вы пользуетесь наиболее часто. Может так оказаться, что вся ваша квартира будет забита одеждой, которую вы редко носите, и ящиками с барахлом, которое вы почти никогда не используете. Если у вас громадный дом с множеством помещений, то ничего ужасного в этом нет, но если вы живете в квартире, то она окажется забитой вещами до потолка. Настольный компьютер — суть "большой дом". Мобильное устройство — суть "квартира".
Очевидно, что должны существовать какие-то правила, регламентирующие, что следует держать под рукой, а от чего необходимо избавляться. Действительно, такие правила существуют но, к счастью, они основываются на здравом смысле, и главное заключается в том, чтобы их систематически применять. Именно в том и состоит на значение явной модели использования памяти приложения, чтобы гарантировать последовательное применение основанных на здравом смысле соображений, обеспечивающих эффективное выполнение мобильного приложения.