MemoryMappedFiles: сколько памяти можно выделить для файлов - PullRequest
5 голосов
/ 01 апреля 2011

У меня большие файлы CT rawdata, размер которых может превышать максимальный размер от 20 до 30 ГБ. Для большинства наших современных компьютеров в отделе у нас есть максимум 3 ГБ. Но для обработки данных нам нужно пройти через все доступные данные. Конечно, мы могли бы сделать это, последовательно просматривая данные с помощью функций чтения и записи. Но иногда необходимо хранить некоторые данные в памяти.

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

В C # я создал частично частично работающий механизм, который автоматически mps и отображает данные при необходимости. Много лет назад я знал MemoryMappedFiles, но в .NET 3.5 я отказался использовать его, потому что знал, что в .NET 4.0 он будет доступен изначально.

Итак, сегодня я попробовал MemoryMappedFiles и обнаружил, что невозможно выделить столько памяти, сколько необходимо. Если у меня 32-битная система и я хочу выделить 20 ГБ, она не работает из-за превышения размера логического адресного пространства. Это как-то понятно мне.

Но есть ли способ обработки таких больших файлов, как у меня? Какие еще у меня есть шансы? Как вы, ребята, решаете такие вещи?

Спасибо Martin

Ответы [ 4 ]

3 голосов
/ 02 апреля 2011

Единственное известное мне ограничение - это размер самого большого представления файла, который вы можете отобразить, который ограничен адресным пространством.Файл сопоставленной памяти может быть больше адресного пространства.Windows необходимо отобразить представление файла в непрерывном фрагменте адресного пространства вашего процесса, поэтому размер наибольшего сопоставления равен размеру самого большого свободного фрагмента адресного пространства.Единственное ограничение на общий размер файла устанавливается самой файловой системой.

Взгляните на эту статью: Работа с большими файлами, отображенными в память

2 голосов
/ 02 апреля 2011

«Память сопоставлена», вы не можете отобразить 20 гигабайт в виртуальное адресное пространство 2 гигабайта. Получить 500 МБ в 32-битной операционной системе сложно. Имейте в виду, что это , а не хорошее решение, если вам не нужен тяжелый произвольный доступ к данным файла. Что должно быть сложно, когда нужно разделить представления. Последовательный доступ через обычный файл непобедим при очень скромном использовании памяти. Также остерегайтесь затрат на маршалинг данных из MMF, вы все равно платите за копию управляемой структуры или затрат на маршалинг.

1 голос
/ 02 апреля 2011

Вы по-прежнему можете последовательно читать файл, вы просто не можете хранить более 2 ГБ данных в памяти.

Вы можете отображать блоки файла одновременно, предпочтительно блоки, кратные вашейstruct.

например.Файл 32 ГБ.Карта памяти 32MB файла за раз и анализируем его.Как только вы достигнете конца этих 32 МБ, отобразите следующие 32 МБ файла и продолжайте, пока не достигнете конца файла.

Я не уверен, каков оптимальный размер отображения, но этопример того, как это можно сделать.

0 голосов
/ 02 апреля 2011

Вы оба правы.Сначала я попытался использовать файл с картой памяти без файла.Там это не работает.Если у меня есть существующий файл.Я могу отобразить столько памяти, сколько захочу.Причина, по которой я хотел использовать MemoryMappedFiles без реального существующего файла, заключается в том, что он должен автоматически удаляться при удалении потока.Это не поддерживается MemoryMappedFile.

Что я увидел сейчас, так это то, что я могу сделать следующее, чтобы получить ожидаемый результат:

       // Create the stream
        FileStream stream = new FileStream(
            "D:\\test.dat", 
            FileMode.Create, 
            FileAccess.ReadWrite, 
            FileShare.ReadWrite, 
            8, 
            FileOptions.DeleteOnClose // This is the necessary part for me.
            );

        // Create a file mapping
        MemoryMappedFile x = MemoryMappedFile.CreateFromFile(
            stream,
            "File1", 
            10000000000, 
            MemoryMappedFileAccess.ReadWrite, 
            new MemoryMappedFileSecurity(),
            System.IO.HandleInheritability.None, 
            false
            );

        // Dispose the stream, using the FileOptions.DeleteOnClose the file is gone now
        stream.Dispose();

По крайней мере, если смотреть на первый результат, который выглядитхорошо для меня.

Спасибо.

...