Сколько памяти занимает открытие файла в современной системе Windows? Для загрузки некоторых приложений потребуется открыть «много» файлов. Windows очень способна открывать «много» файлов, но какова нагрузка на то, чтобы держать один файл открытым, чтобы можно было решить, когда «много» — это «слишком много»?
Для последовательной обработки наборов данных большого размера (100 МБ ~ несколько ГБ) внутри 32-битного процесса нам необходим буфер, который хранит свое содержимое на диске, а не в памяти.
Мы выделили небольшой класс без особых проблем (используя CreateFile
с FILE_ATTRIBUTE_TEMPORARY
а также FILE_FLAG_DELETE_ON_CLOSE
).
Проблема в том, что способ использования этих буферов таков, что каждый буфер (каждый временный файл) может потенциально хранить от нескольких байтов до нескольких ГБ данных, и мы хотели бы сохранить сам класс буфера как минимальный и как Вообщем как можно.
Вариант использования варьируется от 100 буферов с ~ 100 МБ каждый до 100 000 с буфером всего по несколько байтов каждый. (И да, важно, чтобы каждый буфер в этом смысле имел свой собственный файл.)
Казалось бы естественным включить пороговое значение буфера в буферный класс, который начинает создавать и использовать временный файл на диске, когда он на самом деле хранит больше байтов, чем (память) накладные расходы на создание + ссылки на использование временного файла — в процессе как а также нагрузка на память физической машины.
Сколько памяти (в байтах) занимает открытие (временного) файла в современной системе Windows?
CreateFile
с FILE_ATTRIBUTE_TEMPORARY
а также FILE_FLAG_DELETE_ON_CLOSE
То есть, каково пороговое значение в байтах, когда вы начинаете видеть чистый выигрыш в основной памяти (как в процессе, так и физически) от хранения данных в файле, а не в памяти?
Упомянутый комментарий лимит открытого файла не относится к CreateFile
, только для API файла MS CRT. (Открытие 10.00s файлов через CreateFile не является проблемой для моей системы — вопрос о том, хорошая ли это идея, — это совсем другой вопрос, и не является частью этого вопроса.
Файлы с отображенной памятью: Абсолютно не подходят для обработки ГБ данных в 32-битном процессе, поскольку вы не можете надежно отобразить такие большие наборы данных в обычный диапазон адресов 2 ГБ 32-битного процесса. Являются полностью бесполезен для моей проблемы и никак не связан с реальным вопросом. Простые файлы просто отлично подходят для фоновой проблемы.
Посмотрел на http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx — который говорит мне, что HANDLE
сам по себе занимает 16 байт в 64-битной системе, но это просто рукоять.
Посмотрел на STXXL и это документы, но ни эта библиотека не подходит для моей задачи, ни я не нашел упоминания о полезном пороге, прежде чем начать на самом деле использовать файлы.
Раймонд пишет: «Ответ будет зависеть от того, какое антивирусное программное обеспечение установлено, поэтому единственный способ узнать это — протестировать его на рабочей конфигурации».
qwm пишет: «Я бы больше заботился о накладных расходах процессора. В любом случае, лучший способ ответить на ваш вопрос — это проверить его. Все, что я могу сказать, — это размер _FILE_OBJECT
один (включая _OBJECT_HEADER
) составляет ~ 300b, а некоторые из его полей являются указателями на другие связанные структуры «.
Damon ВИРтес: «Один правильный ответ: 10 байт (на моем компьютере с Windows 7). Поскольку никто другой не посчитал, что стоит попробовать, я сделал (измерил разницу в MEMORYSTATUSEX::ullAvailVirtual
более 100к звонков, больше ничего не работает). Не спрашивайте меня, почему это не 8 или 16 байтов, я бы не знал. Потребовалось около 17 секунд времени ядра, при выходе из процесса было открыто 100 030 дескрипторов. Частный рабочий набор увеличивается во время работы на 412 КБ, тогда как глобальная доступная ВМ уменьшается на 1 МБ, так что примерно 60% накладных расходов памяти находится внутри ядра. (…)»
«Что более удивительно, так это огромное количество времени ядра (которое заняло процессорное время, а не ожидание на диске!), Которое CreateFile
очевидно потребляет. 17 секунд для вызовов 100 000 сводится к примерно 450 000 циклов открытия одной ручки на этом аппарате. По сравнению с этим, всего лишь 10 байтов виртуальной памяти уходят незначительно «.
Я сейчас сделал несколько измерений:
Вызов для создания временного файла (и я сохраняю его дескриптор до конца) выглядит следующим образом:
HANDLE CreateNewTempFile(LPCTSTR filePath) {
return ::CreateFile(
filePath,
GENERIC_READ | GENERIC_WRITE, // reading and writing
FILE_SHARE_READ, // Note: FILE_FLAG_DELETE_ON_CLOSE will also block readers, unless they specify FILE_SHARE_DELETE
/*Security:*/NULL,
CREATE_NEW, // only create if does not exist
FILE_ATTRIBUTE_TEMPORARY | // optimize access for temporary file
FILE_FLAG_DELETE_ON_CLOSE, // delete once the last handle has been closed
NULL);
}
Результаты:
Обратите внимание, что я также отслеживал подкачку страниц, и файл подкачки вообще не использовался (как я и надеялся, поскольку на этой машине было 16 ГБ ОЗУ, а в самой нижней точке у меня оставалось ~ 4 ГБ).
Других решений пока нет …