Можно ли избежать копирования данных при использовании файлов с отображением памяти в С#?

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

Я предполагаю, что это связано с тем, что указатели и сборщик мусора вообще не ладят друг с другом.

Итак, есть ли способ обойти это?

  • Возможно, через какой-то смешанный режим C++, который может предоставлять управляемый API поверх данных, отображаемых в памяти?
  • Как насчет прямого манипулирования указателями с небезопасным C#?

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

Кстати, не делает ли это .NET API бесполезным для сценария «совместного использования больших объемов данных»?


person David    schedule 14.05.2012    source источник
comment
code.msdn.microsoft.com/windowsdesktop/   -  person Robert Harvey    schedule 15.05.2012
comment
Вы читаете весь файл сразу в приложение .NET? Если вы читаете части отображаемого в память файла по мере необходимости, вы выделяете много небольших буферов, но это не так дорого, как вы думаете. Можно избежать копирования, но действительно ли накладные расходы на копирование являются проблемой?   -  person Dan Bryant    schedule 15.05.2012
comment
У меня есть приложения .NET, которые очень эффективно совместно используют большие объемы данных несколькими способами, включая файлы с отображением памяти. В частности, один пакет разделяет более 8 гигабайт, а общее использование памяти этими программами на удивление близко к 8 гигабайтам.   -  person Jim Mischel    schedule 15.05.2012
comment
Я бы прочитал все содержимое сразу. Если я сделаю копию в каждом процессе, которому нужна структура данных, то я ничего не сохранил от использования MMF, с тем же успехом мог бы использовать файловый поток.   -  person David    schedule 15.05.2012


Ответы (1)


Вы можете использовать небезопасный код для прямого доступа к отображаемой памяти. Я предлагаю вам изучить «преобразуемые структуры», которые представляют собой типы структур, которые можно копировать в память без изменений. Вот пример:

struct MyDataRecord { public int X, Y; }

...

for (var i = 0 .. 10) {
 ((MyDataRecord*)pointerToUnmanagedMemory)[i] = new MyDataRecord() { X = i, Y = i * i };
}

Это очень эффективно и удобно.

person usr    schedule 14.05.2012
comment
Хм, вы пропустили именованный мьютекс, необходимый для того, чтобы процесс не читал записываемые данные. У этого есть умение выбрасывать удобного из окна. И убить перф. - person Hans Passant; 15.05.2012
comment
Похоже, небезопасный код и преобразовываемые структуры будут правильным решением... Спасибо, @usr. Я также нашел это после того, как включил небезопасный в свой поиск: in-net" title="как я могу быстро прочитать байты из файла с отображением памяти в сети"> stackoverflow.com/questions/7956167/ - person David; 15.05.2012