Etc.: Упаковщики - ЗА и ПРОТИВ
Автор: Jordan Russell
Многие посетители моей страницы часто спрашивают следующее:
"Если я хочу уменьшить размер своей программы, то почему бы ни использовать EXE компрессор? Это позволит сделать размер EXE значительно меньше, чем использование StripReloc! Почему вы против этого"
Многие не понимают (или просто не знают), что при использовании компрессоров типа ASPack и UPX они многое теряют. По моему мнению EXE компрессоры это не то, что следует применять бездумно. Позвольте разъяснить.
В DOS, когда вы запускаете программу, весь ее код загружается с диска В оперативную память и остается в ней до конца. Если не хватает памяти для загрузки всей программы, то вы получите сообщение об ошибке "out of memory".
Современные многозадачные Операционные Системы (ОС), такие как Windows 95/98 и NT используют метод названный "Виртуальная память" (virtual memory). Когда программа загружается, то в память сразу не грузится весь код, как в случае DOS программ. Вместо этого загружается только часть кода, которая требуется для исполнения. Например, ваша программа имеет пункт меню "Print" и код назначенный, который исполняется при выборе этого пункта. Этот код загружается в память только когда пользователь выбирает данный пункт. И если после загрузки кода в память он не используется некоторое время, то код выгружается из памяти, память освобождается и может быть использована другими программами. Данный процесс называется "paging" и полностью прозрачно для программы.
Другой путь экономии использования памяти - это использование одной и той же области памяти для нескольких экземпляров программы (или DLL). Другими словами, нет реальной разницы между одним экземпляром программы или сотней экземпляров программы в количестве используемой физической памяти выделенной для кода.
Если бы Win32 вели бы себя как DOS программы, то есть загрузка всего кода в память и оставались бы там до завершения и также бы не разделяли память для разных экземпляров программы, вы бы быстро исчерпали всю доступную память.
Вот именно это и делают текущие Win32 EXE компрессоры! Они полностью блокирую работу метода "paging" разжимая весь код в память и сохраняя его там до конца работы программы. И поскольку код в упакованном EXE файле хранится не в обычном "raw" формате (то есть в том виде какой он в памяти), то ОС не в состоянии разделять тот же блок памяти для нескольких экземпляров программы. Многие используют EXE компрессоры как сильное оружие для уменьшения потерь под размер на диске, но я хочу спросить: Что более накладно - мегабайты на диске или мегабайты оперативной памяти? Действительно ли стоит увеличивать требования вашей программы на оперативную память за счет сохранения несколько килобайт дискового пространства?
Тестирование
Я слышал, что многие сжимают свои EXE из MS Office, поэтому я решил провести тест по реальному использованию памяти именно на MSACCESS.EXE. Я сжал MSACCESS.EXE из Office 2000 с помощью UPX и сравнил использование памяти с помощью NT 4.0's Task Manager...
Ниже приведены (удивительные) результаты теста.
| File Size | Process "Mem Usage" 1 instance | "Commit Charge Total" 1 instance difference | "Commit Charge Total" 20 instances difference |
uncompressed | 4,677,686 | 2580 KB | 1084 KB | 25396 KB |
UPX 0.82 | 2,436,096 | 6852 KB | 6192 KB | 126968 KB |
Опираясь на 1 экземпляр результаты показанные выше, показываю что: сжатый MSACCESS.EXE забирает на 5MB больше памяти. Ну не так уж плохо, но уже ощутимо.
Но вот уже для 20 экземпляров результат следующий. Да вы читаете правильно. Это не типографская ошибка!!! Для 20 экземпляров сжатого MSACCESS.EXE требуют на 100 Мб больше, чем не сжатый.
Мой тест был сделан на машине с 256MB оперативной памяти, желаю удачи при проведении теста на машине с 64 Мб память. Для запуска 20 экземпляров MSACCESS.EXE я использовал 20 строчный bat файл, каждая строка которого содержала следующий тест: "START MSACCESS.EXE". Плохая весть: запуск 20 экземпляров MSACCESS.EXE немного больше времени (4 секунды против 1.5), которое я отношу на счет взаимного использования кода между экземплярами и времени требуемым на распаковку программы. Это показывает, что малый размер файла не гарантирует более быструю загрузку.
Поскольку я делал фокус на тестирования кода, я использовал следующие ключи для UPX: --compress-exports=0 --compress-icons=0 --compress-resources=0. Я планировал протестировать и ASPack, но запустить сжатый MSACCESS.EXE не удалось. Но я думаю, что результат был бы сравним с UPX, также я не пробовал тестировать другие упаковщики.
Заключение
Цель данной статьи не является принизить авторов EXE компрессоров, а только отражает факты, о которых они предпочитают умалчивать. Да EXE компрессоры могут быть хорошим выбором когда нужно. Но в то же время много причин не получения нужного результата, как это показывает мой тест.
Дополнение от 20 апреля 2000
Другой недостаток использования EXE компрессоров, не отмеченный выше, это то что многие старые сканеры вирусов считаю, что в эти упакованные файлы заражены вирусом, (некоторые из них докладывают "неизвестный вирус", некоторые "Win32.BackDoor"). Это было основной причиной для отказа использования в моем инсталляторе "Inno Setup", а не по причине расточительного использования памяти. Я был очень огорчен ругательными письмами, которые я стал получать по поводу распространения вирусов. Я даже был обозван лжецом, когда пытался объяснить это. Пришлось даже увидеть предупреждение на некоторых сайтах, о том, что "Inno Setup" может содержать вирус. Как результат, использование EXE компрессоров может привести к потере бизнеса или подрыву репутации.
Я конечно не думаю, что кто то будет запускать 20 экземпляров MS Access одновременно. Это было сделано с целью иллюстрации, что затраты на память возрастаю экспоненциально при запуске нескольких экземпляров. В большинстве случаев не запускают нескольких экземпляров программ, но DLL часто загружаются и используются одновременно несколькими программами. Взаимное использование кода относится и к DLL также, о чем я забыл упомянуть в статье.
Многие люди спрашивают, "а как насчет Shrinker?" Blink, Inc. преподносит, что Shrinker "единственный продукт, который распаковывает EXE блоками по требованию (ON DEMAND), а не при запуске программы", и это объясняет почему распаковщик занимает примерно 30 килобайт для каждой программы. Мои начальные тесты со Shrinker были неполными и проведу дополнительное тестирование Shrinker в будущем.
Примечание переводчика:
Джордан Рассел (Jordan Russell) автор программ и компонент Inno Setup, StriLIloc, ToolBar97, ToolBar 2000
Оригинал находится http://www.jordanr.dhs.org/striprlc.htm
Перевод: Анатолий Подгорецкий, 21.04.2000
См. также статью Криса Касперски "Паковать или не паковать?"