在C#中使用内存映射文件时,是否可以避免数据副本? [英] Is it possible to avoiding copies of data when using memory mapped files in C#?

查看:56
本文介绍了在C#中使用内存映射文件时,是否可以避免数据副本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对内存映射文件在C#中的工作方式的理解是,每次对数据的请求都会产生一个副本.例如,如果您有一个较大的数据结构作为文件持久存储,那么使用内存映射文件将导致实际文件的内存映射到RAM,并且一旦从文件中读取了副本,副本就会驻留在GC堆中.>

我认为这是因为指针和GC总体上相处不好.

那么,有什么办法解决这个问题?

  • 也许通过某种可以在内存映射数据上公开托管API的混合模式C ++?
  • 使用不安全的C#直接进行指针操作怎么办?

我要解决的一般问题是在多个进程之间共享大型数据结构.数据结构用于回答一小部分问题",这些问题可以作为简单的API公开(即,基本上,是一堆其他数据的高度专业化的索引).

另一方面,这是否会使.NET API在共享大量数据"的情况下无用?

解决方案

您可以使用不安全的代码直接访问映射的内存.我建议您研究可漂白结构",它们是可以在内存中复制而无需修改的结构类型.这是一个示例:

  struct MyDataRecord {public int X,Y;}...对于(var i = 0 .. 10){((MyDataRecord *)pointerToUnmanagedMemory)[i] = new MyDataRecord(){X = i,Y = i * i};} 

这非常高效且很方便.

My understanding of how memory mapped files work in C# is that every request for data results in a copy. For instance, if you had a large data structure persisted as a file, using a memory mapped file would result in memory for the actual file mapped into RAM, and a copy residing in a GC heap once it was read from the file.

I'm assuming this is because pointers and the GC don't get along well together generally speaking.

So, is there any way around this?

  • Perhaps via some mixed mode C++ that can expose a managed API over the memory mapped data?
  • What about direct pointer manipulation with unsafe C#?

The general problem I'm trying to solve is sharing a large data structure between multiple processes. The data structure is used to answer a small set of "questions" that can be exposed as a simple API (i.e. basically, a highly specialized index of a bunch of other data).

On a side note, doesn't this make the .NET API useless for the "sharing large amounts of data" scenario?

解决方案

You can use unsafe code to directly access the mapped memory. I suggest you look into "blittable structs" which are struct types which can be copied around in memory without modification. Here is an example:

struct MyDataRecord { public int X, Y; }

...

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

This is very performant and kind of convenient.

这篇关于在C#中使用内存映射文件时,是否可以避免数据副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆