Страница 1 из 1

Ограничения (баги?) при открытии и навигации в архивах

Добавлено: Ср май 14, 2014 20:02
LonerD
Дано: TC 8.51a x32, Windows 8.1 x64 SL (6.3.9600), места для Temp и лог-файлов предостаточно, оперативки - 32 Гб.
Архив - 7zip, внутри 3.6 млн файлов (разложенные по каталогам и подкаталогам, в корне архива - 319 каталогов), в сжатом виде - 5.1 Гб, в распакованном - около 43 Гб. Рядом (или на другом диске - без разницы) лежит этот же архив под другим именем.
Вхожу в архив штатными средствами TC. Медленно, но входит, памяти отжирается до 1.3 Гб в процессе открытия архива (после открытия - 750 Мб). Выхожу, при этом процесс Тотала продолжает отжирать 750 Мб оперативки. Пытаюсь войти во второй архив - "Error in packed file". При этом оперативка очищается (диспетчер задач показывает, что занято 7.1 Мб), но войти невозможно уже ни в первый ни во второй архив - выбивает всё ту же ошибку. Лечится перезапуском Тотала.

А вот TC x64 - свободно входит в оба архива одновременно.
Памяти Тотал начинает отжирать до 3 Гб при входе (до 2 Гб после входа).

Насколько я понимаю, проблема с TC x32 в том, что он может использовать только ограниченное количество оперативки. Это баг или очередное бессмысленное ограничение Тотала? Ведь 64-х битная ОС позволяет выделять приложениям неограниченное количество памяти (и нет ограничений на размер непрерывного блока, выделяемого приложению в оперативке).
Но даже если и так - почему после очищения оперативки Тотал отказывается входить в архивы? Это уже явный баг.

Очень медленная навигация внутри архива. Причём без разницы - хоть архив на медленном диске, хоть на SSD. Если вначале перечитывается всё содержимое архива - то почему медленно открываются подкаталоги? Если вначале читается только корень архива - то почему три десятка каталогов так медленно перечитываются? В любом случае - ведь используется 7-zip библиотека, а сам архиватор 7-Zip довольно шустро работает с этим же архивом.

Отдельный вопрос - почему оперативка не очищается при выходе из архива? Как-то не комильфо, когда архиватор (64-х битная версия) пожирает всё больше и больше ресурсов. Наверное, логично будет попросить Гислера сделать отдельную команду или настройку для очищения неиспользуемой памяти.

Добавлено: Ср май 14, 2014 20:40
MVV
Если логически подумать, в 32-битных процессах 32-битные указатели, что уже ограничивает адресное пространство до 4 ГБ, даже если система имеет их в наличии 100500. А если знать, что половину адресного пространства забирает себе система, то для нужд самого тотала остается никак не более 2 ГБ - это для тотала и всех не системных библиотек, хуков и прочей ереси. Это не ограничение тотала, это ограничение 32-битных программ.

А почему тотал повторно не может зайти в тот же архив после освобождения памяти - хороший вопрос. Как себя ведут себя плагины 7z в такой ситуации?

Добавлено спустя 5 минут:

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

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

Добавлено: Ср май 14, 2014 23:04
CaptainFlint
LonerD писал(а):Насколько я понимаю, проблема с TC x32 в том, что он может использовать только ограниченное количество оперативки. Это баг или очередное бессмысленное ограничение Тотала? Ведь 64-х битная ОС позволяет выделять приложениям неограниченное количество памяти (и нет ограничений на размер непрерывного блока, выделяемого приложению в оперативке).
Как выше написал MVV, воспользоваться сиими благами сможет только 64-битный процесс. 32-битному для этого надо извращаться с AWE, что Гислера, видимо, нисколько не вдохновляет, тем более, что нужно это лишь для подобных, прямо скажем, не очень часто встречающихся ситуаций.

Немножко лучше обстоит дело, если 32-битный процесс имеет флаг LARGE_ADDRESS_AWARE: тогда 64-битная система может дать ему доступ ко всему 4-гигабайтному адресному пространству, не отбирая оттуда 2 Гб под свои нужды. Но у Тотала этот флаг не установлен (Гислер говорит, соответствующей опции нет в линкере Delphi).
LonerD писал(а):Очень медленная навигация внутри архива.
Работа с архивами производится не так, как с обычной файловой системой. Список файлов там обычно не делится по каталогам, а хранится сплошняком (в виде относительных путей) и поэтому грузится в память целиком. Так что каждое действие по навигации приводит к поиску и фильтрации всего этого списка из 3,6 млн записей для выдачи содержимого конкретного подкаталога. Понятно, что это — дело небыстрое. Скорость диска роли не играет, т.к. список весь в памяти.
LonerD писал(а):а сам архиватор 7-Zip довольно шустро работает с этим же архивом.
Тотал жёстко связан RAR-подобным плагиновым интерфейсом. Я не знаю ни структуры 7z-архивов, ни кода 7-Zip, но очень может быть, что для навигации там используются дополнительные возможности, не укладывающиеся в рамки WCX API. Впрочем, не исключено, что Гислер просто не исследовал этот сценарий, и там ещё есть резервы по оптимизации.

Добавлено: Ср май 14, 2014 23:24
MVV
CaptainFlint писал(а):Немножко лучше обстоит дело, если 32-битный процесс имеет флаг LARGE_ADDRESS_AWARE: тогда 64-битная система может дать ему доступ ко всему 4-гигабайтному адресному пространству, не отбирая оттуда 2 Гб под свои нужды. Но у Тотала этот флаг не установлен (Гислер говорит, соответствующей опции нет в линкере Delphi).
Насколько я знаю, бит LARGE_ADDRESS_AWARE - лишь указание системе, что приложение понимает беззнаковые указатели, и может помочь лишь в случае, когда в системе сдвинута граница юзер-ядро с исходной 2-2 на, скажем, 3-1. Системные библиотеки всё равно будут загружаться по своим же адресам, и фрагментация памяти никуда не денется.
Тотал жёстко связан RAR-подобным плагиновым интерфейсом. Я не знаю ни структуры 7z-архивов, ни кода 7-Zip, но очень может быть, что для навигации там используются дополнительные возможности, не укладывающиеся в рамки WCX API. Впрочем, не исключено, что Гислер просто не исследовал этот сценарий, и там ещё есть резервы по оптимизации.
У 7Z структура гораздо более продвинутая, чем у RAR (позор Рошалу, что в RAR5 в этом плане ничего принципиально не изменилось): там информация о файлах хранится в виде таблицы в одном месте архива, и заодно сжимается с помощью того же LZMA, не надо бродить по архиву, чтобы прочитать его (когда не было 7Z, одной из причин, по которым я полюбил CAB, было гораздо более быстрое чтение оглавления, т.к. оно там централизованное, да и степень сжатия зачастую не уступала RAR). Интерфейс 7-Zip спокойно обрабатывает архивы, в которых файлы имеют одинаковые имена (инсталлеры, например), в то время как тотальный WCX API такого не позволяет - возможно, обращение по индексам и хранение структуры в виде деревьев повысило бы скорость доступа к файлам. Не говоря уже о том, что не нужен был бы непрерывный блок для хранения оглавления архива.

Добавлено: Чт май 15, 2014 01:13
CaptainFlint
MVV писал(а):Насколько я знаю, бит LARGE_ADDRESS_AWARE - лишь указание системе, что приложение понимает беззнаковые указатели, и может помочь лишь в случае, когда в системе сдвинута граница юзер-ядро с исходной 2-2 на, скажем, 3-1. Системные библиотеки всё равно будут загружаться по своим же адресам, и фрагментация памяти никуда не денется.
Про фрагментацию я ничего и не говорил, а память всё-таки может выделяться вся. Сам не так давно узнал об этом.