Реализация виртуальной памяти с отображенными в память файлами - PullRequest
1 голос
/ 17 ноября 2011

Можно ли обернуть файлы, отображенные в память, примерно так?

TVirtualMemoryManager = class
public
  function  AllocMem (Size : Integer) : Pointer;
  procedure FreeMem (Ptr : Pointer);
end;

Поскольку все функции API для отображения в памяти имеют смещение, я не знаю, как управлять свободными областями в файлах, отображаемых в память. Моя единственная идея - реализовать какое-то базовое управление памятью (ведение свободных списков для блоков разных размеров), но я не знаю, насколько это будет эффективно.

РЕДАКТИРОВАТЬ : То, что я действительно хочу (как Дэвид дал мне понять), это:

IVirtualMemory = interface
  function  ReadMem (Addr : Int64) : TBytes;
  function  AllocateMem (Data : TBytes) : Int64;
  procedure FreeMem (Addr : Int64);
end;

Мне нужно хранить непрерывные блоки байтов (каждый относительно небольшой) в виртуальной памяти и иметь возможность считывать их обратно в память, используя 64-битный адрес. В большинстве случаев доступ только для чтения. Если запись необходима, я бы просто использовал FreeMem, а затем AllocMem, поскольку размер все равно будет другим.

Я хочу обертку для файла с отображением в памяти с этим интерфейсом. Внутренне он имеет дескриптор отображенных в память файлов и использует MapViewOfFile при каждом запросе ReadMem. Addr 64-битные целые числа просто смещаются в отображенный файл памяти. Открытый вопрос - как назначить эти адреса - в настоящее время у меня есть список свободных блоков, которые я поддерживаю.

1 Ответ

2 голосов
/ 17 ноября 2011
  1. Ваше предложение о том, что " Внутренне имеет дескриптор отображаемых в памяти файлов и использует MapViewOfFile при каждом запросе ReadMem ", будет пустой тратой ресурсов процессора, ИМХО.

  2. Стоит сказать, что ваше требование GetMem / FreeMem не сможет преодолеть барьер 3/4 ГБ.Поскольку вся выделенная память будет отображаться в памяти до вызова FreeMem, вам не хватит места в памяти, как и в обычном диспетчере памяти Delphi.Лучшее, что вы можете сделать, - это положиться на FastMM4 и изменить свою программу, чтобы уменьшить использование памяти.

  3. ИМХО вам придется изменить / обновить свою спецификацию.Например, ваш «обновленный» вопрос звучит так же, как обычная проблема с хранилищем.

Вам нужно иметь возможность выделить более 3/4 ГБ данных для вашего приложения.У вас есть рабочая реализация такой функции в нашем SynBigTable модуле с открытым исходным кодом.Это быстрое и легкое NoSQL решение на чистом Delphi.

Оно способно создать файл любого размера (только 64-битное ограничение), затем отобразит содержимое каждой записи впамять, по запросу.Он будет использовать отображение памяти файла, если это возможно.Вы можете реализовать свой интерфейс очень напрямую с помощью TSynBigTable методов: ReadMem=Get, AllocMem=Add, FreeMem=Delete.Идентификаторы будут вашими pointer -подобными значениями, и вместо TBytes будет использоваться RawByteString. Вы можете получить доступ к любому блоку данных, используя целочисленный идентификатор, или идентификатор строки, или дажеиспользуйте сложную структуру полей (внутри записи или в виде метаданных в памяти - включая индексы и быстрый поиск).

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

...