MemoryMappedFile 或序列化,超大对象的速度
Posted
技术标签:
【中文标题】MemoryMappedFile 或序列化,超大对象的速度【英文标题】:MemoryMappedFile or serialization, speed on very large object 【发布时间】:2012-02-21 06:43:31 【问题描述】:我有一个项目,它有一个相当复杂的嵌套(引用向上和向下调用引用的对象)对象(类)存储在字典中,例如:
public static Dictionary<string, Object1> DObject get; set;
Object1 是一个复杂的类。它不像“地址簿”或“个人信息”类。类本身有数组,另一个对象的字典。那些对象引用它上面的类,等等。
因为 DObject 在内存中的大小可以是 1GB+,所以我将使用 BinaryFormatter 将它序列化为一个文件。因为我需要加载这个对象,所以我正在考虑使用 MemoryMappedFile。新的键和值可能会添加到字典中。对象中可能有更多数据(添加/更新)等。MMF 是否改变大小?如何访问内存映射文件中 DObject 中的某个键?内存中是否有像哈希表这样的搜索机制,所以我可以像字典一样找到某个键并获取它的值?这个 MMF 是如何工作的?
我的理想想法是。在磁盘上有一个大文件(2GB+)。我在磁盘上快速更新字典中的对象,就像在磁盘上保存内存一样。一切都很快。键值查找一路。我查找、编辑值、保存等……我必须随时快速访问这个 2GB+ 的对象。如果 WCF 服务器重新启动,我需要快速访问这个 2GB+ 大小的对象。这就是为什么我在想1)序列化2)。从/向 MMF 加载和读取。我现在主要关心的是速度。换句话说,我每次调试项目时都不能从头开始重新加载这 2GB 数据(这需要很长时间)。
关于我应该如何处理这种情况的任何建议、想法和想法。
【问题讨论】:
对于长期持久性,您可能会遇到 binaryformatter 的问题(例如,更改命名空间会很快导致问题)。对于短期存储可能没问题,但要小心内存使用,我认为您不能在 32 位进程中使用 binaryformatter 序列化 1Gb 图形而不会出现问题。如果您认为映射到表会给您带来阻抗问题,也许您可以考虑使用 RavenDB 等文档数据库,它将整个文档图映射到磁盘上的 JSON 并为您处理很多性能问题? 这些数据库中的任何一个都可以将对象图(20 个相互关联的类)解析为 JSON/BSON 并保留它们之间的所有引用然后存储吗?这是如何运作的?我的理想想法是直接将 DObject 提供给 RavenDB 或 MongoDB,然后它们会序列化并存储所有内容?如果我想将 DObject 放入 RavenDB,步骤是什么?我是 MongoDB 新手,但听说过很多。 RavenDB 是否会直接吞下您的对象取决于您的对象的结构。 RavenDB 使用 JSon.NET,因此您始终可以尝试使用 Json.NET 转储根对象,然后看看您能走多远。 好的。在这一点上,我将使用 MongoDB。我稍后会检查 RavenDB。 MongoDB 似乎是对的。这些数据必须进入我现在发现的某种数据库。我不能长期序列化和保存数据。 【参考方案1】:您不能将DObject
本身保存在内存映射文件中。 .NET 对象往往一直在移动,您不能强迫它们停留在内存中的一个位置(您可以固定它们,但您真的不想这样做)。您可以序列化对象并将其写入文件,但这意味着每次要写入超过 1GB 的数据。
为什么不采用标准方式,将您的对象“序列化”为一组数据库表?
【讨论】:
我该怎么做?该对象不是简单的“人员信息”或“联系信息”列表。对象本身具有键值对字典。字典的值有“列表”,而这些列表中可能有“字典以上是关于MemoryMappedFile 或序列化,超大对象的速度的主要内容,如果未能解决你的问题,请参考以下文章
.net 4.0 创建具有全局上下文的 MemoryMappedFile 会引发异常