Освобождение виртуальной памяти, зарезервированной C ++, «новым» в Windows - PullRequest
2 голосов
/ 25 мая 2011

Я пишу 32-битную программу .NET с двухэтапным процессом ввода:

  1. Он использует собственный C ++ через C ++ / CLI для анализа файлов с неопределенным числом в соответствующие базы данных SQLite (все с одной и той же схемой). Выделения в C ++ «new» обычно занимают до 1 ГБ виртуального адресного пространства (из 2 ГБ доступно; я знаю о расширении 3 ГБ, но это только задержит проблему).

  2. Он использует сложные запросы SQL (запускаются из C #) для объединения баз данных в одну базу данных. Я установил для cache_size значение 1 ГБ для объединенной базы данных, чтобы в объединяемой части было минимальное количество ошибок страницы.

Моя проблема в том, что кэш на этапе 2 не использует повторно 1 ГБ памяти, выделенной функцией «new» и правильно освобожденной командой «delete» на этапе 1. Я знаю, что утечки нет, потому что сразу после выхода из этапа 1 » количество частных байтов падает до небольшого количества, как я и ожидал. «Виртуальный размер», тем не менее, остается на пике использования C ++.

Это отсутствие совместного использования между C ++ и SQLite кешем приводит к тому, что у меня заканчивается виртуальное адресное пространство. Как я могу решить эту проблему, желательно в соответствии со стандартами? Я действительно хотел бы освободить память, выделенную C ++, обратно в ОС.

Ответы [ 4 ]

4 голосов
/ 25 мая 2011

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

Возможным решением было бы перемещение части C ++ во внешний процесс , который завершается после создания баз данных SQLite. Наличие внешнего процесса вызовет некоторое раздражение (например, немного сложнее сохранить «живой» контроль над происходящим), но также открывает больше возможностей, таких как параллельная обработка, даже если библиотеки не поддерживают многопоточность или используют несколько машин по сети.

2 голосов
/ 25 мая 2011

Поскольку вы взаимодействуете с C ++ / CLI, вы предположительно используете компилятор Microsoft.

Если это так, то вы, вероятно, захотите посмотреть _heapmin.После выхода из «этапа 1» вызовите его, и он освободит блоки памяти, удерживаемые диспетчером кучи C ++, обратно в ОС, если весь блок, выделенный из ОС, теперь свободен.

0 голосов
/ 25 мая 2011

Вы можете выделить его из GC из C #, закрепить, использовать и затем разрешить его возврату, освобождая его и позволяя GC сжать его и повторно использовать память.

0 голосов
/ 25 мая 2011

В Linux мы использовали Google Malloc (http://code.google.com/p/google-perftools/). У него есть функция для освобождения свободной памяти для ОС: MallocExtension::instance()->ReleaseFreeMemory().

Теоретически, gcmalloc работает в Windows, но я никогда не использовал личноэто там.

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