четверг, 19 февраля 2009 г.

Минимизация ущерба от апплетов

Это перевод Applet mitigations. Автор: Ларри Остерман.

Как я упоминал ранее, апплеты могут стать чумой вашей машины. Самое противное, что при этом ведь возможно писать апплеты так, чтобы они не были столь ужасны. И большинство таких техник это просто применение здравого смысла - в них нет совершенно ничего сложного.

Как и в предыдущих постах серии, некоторые из этих способов применимы к любым типам апплетов (и приложениям тоже), а другие являются особенными для конкретного типа.

Давайте начнём с общих способов...

Для апплетов, которые работают постоянно:

Вам ДЕЙСТВИТЕЛЬНО необходимо, чтобы ваш апплет работал всё время? Лучшим апплетом является такой, который не запускается вообще. Нельзя ли переместить функциональность апплета в ваше приложение, которое запускает пользователь? Меню Пуск подсвечивает недавно установленные программы, так что ваше приложение будет хорошо заметно. В худшем случае есть и другие механизмы, чтобы показать вашу программу пользователям (например: рабочий стол (хотя у него тоже есть свои особенности)).

Теперь, когда вы решили, что вам нужен постоянно работающий апплет - пересмотрите это решение. Я серьёзно! Да, я знаю, что я только что уже просил вас подумать об этом. Стив Балмер сказал, что когда-нибудь в 2008, целый миллиард людей будет использовать хоть одну версию Windows - а это КУЧА народу. Если ваш продукт станет успешным - весьма вероятно, что вы продадите его парочке миллионов из них - вы действительно полагаете, что ваш апплет несёт на себе такую полезную функциональность, что будет настолько нужен всем и каждому из этих нескольких миллионов, что вы можете швырнуть его им в лицо? Правда?

Если вы всё же решили, что вам ДЕЙСТВИТЕЛЬНО нужно держать апплет работающим - убедитесь, что у пользователя есть способ его отключить. Нет ничего более раздражающего, чем осознавать, что программа, прилагающаяся к какой-то железяке, которую я используя раз в несколько месяцев, работает постоянно на моей машине.

Если вы собрались писать апплет для того, чтобы пользователь узнал о какой-то новой классной возможности вашей программы, то почему бы вам не использовать ключ RunOnce и сказать пользователю, где он может всё это узнать, затем заткнуться и никогда больше не возникать?



Для всех апплетов (и всех приложений, которые работают постоянно):

Подумайте о том, как уменьшить влияние апплета на систему. Уменьшайте число загружаемых DLL, где это только возможно. Каждая DLL, которую вы загружаете, тратит минимум 4 частных страницы (private page) (16 Кб на x86) и требует от 500К до 1М процессорных циклов для загрузки. Чем меньше у вас DLL - тем лучше. Если вы сможете использовать только kernel32.dll и библиотеку run-time поддержки языка - это хорошо. Рассмотрите возможность отложенной загрузки тех DLL, которые вы редко используете.

Уменьшите размер стека для всех потоков в вашем апплете - по-умолчанию потоки Windows получают по 1 Мб выделенной памяти и 10 Кб резерва (которые на самом деле равны 12 Кб из-за округления на размер страницы). Это означает, что каждый поток гарантировано жрёт как минимум размер своего стека в виртуальной памяти (есть и хорошая новость: поскольку это виртуальная память - то обычно это просто место, зарезервированное в файле подкачки, а не физическая память).

Уменьшайте число процессов, которые требует ваш апплет. Очень редко есть стоящая причина для использования более чем одного процесса. Единственное, что мне сейчас приходит в голову - это разделение функциональности между высоко и низко-привилегированным кодом. Пример этого можно увидеть, например, в Windows Vista, где аудио-стек работает в двух раздельных процессах - службе AudioSrv и службе AudioEndpointBuilder. Это потому, что лишь малая часть звукового движка требует привилегий класса LocalSystem, в то время как большая часть аудио-стека работает отлично с привилегиями простой LocalService. Поэтому служба AudioEndpointBuilder содержит высоко-привилегированный код, а сервис AudioSrv - всё остальное. Если вы думаете, что вам нужен второй процесс для увеличения надёжности (вы запускаете код во внешнем процессе на случай, если он упадёт), то Windows Vista предоставляет вам ещё одну классную возможность под названием "restart manager". Restart manager позволяет ОС перезапускать ваше приложение, если оно вылетает, снижая необходимость для запуска второго процесса.

Не забывайте, что Windows - это многопользовательская система. Некоторое из пользователей одной машины могут не хотеть ваш апплет, а другие - хотеть. Так что убедитесь, что настройка для включения/выключения апплета является пользовательской (per-user). Очень сильно раздражает, когда вы щёлкаете правой кнопкой мыши по иконке в трее и видите, что пункт "выключить эту хрень" не работает, потому что вы работаете из под обычного пользователя (что является обычной ситуацией в Vista). Всякий раз, когда я это вижу, я понимаю, что автор программы не рассматривал (и не тестировал) работу своей программы в случае обыкновенного пользователя.

Если вы можете нацелиться только на Vista, расмотрите вариант понижения приоритетов потоков и ввода-вывода своих апплетов. Если ваш апплет выполняет обработку, не связанную явно с действиями пользователя - используйте новую опцию PROCESS_MODE_BACKGROUND_BEGIN для функции SetPriorityClass, чтобы указать системе, что ваш процесс нужно рассматривать как вспомогательный фоновый процесс - таким способом ваш апплет не отнимет ресурсы у задач пользователя. Вы также можете использовать новый метод FileIoPriorityHintInfo у функции SetFileInformationByHandle для указания ОС низкого приоритета для вашего ввода-вывода.



Далее: минимизация ущерба от обновлялок.

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.