Эквивалент _set_new_handler для VirtualAlloc ()? - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть структура данных для работы с большими наборами данных. По сути, он действует как «просмотр» данных на диске, загружая данные с диска по запросу; он попытается сохранить как можно больше данных в памяти, чтобы при следующем доступе ему не приходилось читать с диска. Когда он обнаруживает нехватку памяти, он выполняет «очистку» кусков данных со счетчиком ссылок 0. Он использует _set_new_handler (), чтобы установить функцию, которая вызывает эту очистку, когда какой-то код пытается где-то выполнить malloc () память, но может «т. Таким образом, структура данных может потреблять как можно больше памяти, но все равно «отступает», когда кому-то еще нужно немного памяти.

Теперь у меня проблема в том, что часть памяти не выделяется с помощью malloc () (или new ()). Я впервые начал видеть это в вызовах CreateDIBSection (), и я думаю, что это потому, что эта функция напрямую использует VirtualAlloc (). Таким образом, когда происходит сбой выделения, новый обработчик не вызывается, а VirtualAlloc просто отказывает. (У меня есть и другие случаи с такой же ситуацией, но те, с которыми я могу обойтись; так что CreateDIBSection () - мой основной «демонстрационный пример» проблемы; но работа с использованием этого конкретного API не решит мою общую проблему)

Так что мой вопрос - есть ли эквивалент _set_new_handler () для VirtualAlloc (), или другой способ уведомления о сбое VirtualAlloc (), чтобы я мог вызвать функцию очистки памяти и попробовать снова выделить? В качестве альтернативы, есть ли способ перехватывать вызовы VirtualAlloc (), чтобы я мог проверять доступность памяти при каждом выделении и очищать при необходимости? Спасибо.

1 Ответ

0 голосов
/ 11 сентября 2018

«Память» не следует понимать как ОЗУ в современной ОС на базе виртуальной памяти - это просто зарезервированный диапазон адресов, который может быть подкреплен файлом подкачки или каким-либо другим отображенным файлом. Операционная система подстраивает память в оперативную память и из нее по требованию, но на самом деле ее следует рассматривать как диск, а не как ОЗУ.

Необходимо соблюдать осторожность, чтобы это учитывалось при попытке создания «кэшей» памяти пользовательского режима, поскольку наивные попытки приведут к чистой потере производительности, поскольку в ОЗУ ничего не будет фактически кэшироваться, и будет ненужное выделение файла подкачки для страница в и из.

Имея это в виду, я могу предложить:

  • Использование MapViewOfFile (и связанных с ним API) для создания файла "view". Это обеспечивает ОС лучшими подсказками о том, что просматриваемый файл напрямую выгружается из своих собственных байтов в оперативную память по желанию и гарантирует, что у вас не будет расточительного копирования и дублирования байтов из исходного файла в файл подкачки.

  • Если вы не можете перестроить как 64-битное приложение, используйте переключатель компоновщика / LARGE_ADDRESS_AWARE в своем приложении, чтобы получить дополнительные 2 ГБ потенциального выделения виртуальной машины.

  • Определите какой-нибудь настраиваемый лимит для вашего распределения: см. Флаг Java runtime -Xmx для примера того, как другие приложения справляются с этим.

  • Вы также можете использовать Расширения Window Addressing для управления доступом к «большим» выделениям из 32-битных приложений.

  • Или рассмотрите возможность использования 64-битного партнерского приложения, которое загружает файл, а затем используйте Разделы общего файла , чтобы управлять общим окном для распределений, сделанных 64-битным приложением.

Прагматично. Я думаю, что использование отображений файлов для создания представления (или представлений) файла будет проще всего реализовать и обеспечить разумную, если не лучшую производительность, даже если представление не отображается в 32-битном процессе, что не означает 64-битная ОС не может или не будет хранить эти байты в оперативной памяти в своем файловом кеше ввода-вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...