我可以使用C#中内存使用量有限的结构(字典)吗?

时间:2015-05-26 13:53:40

标签: c# memory-management dictionary

告诉我哪个库(最好是纯.NET)可以用于以下问题。有

 Dictionary < long, MyData > 
字典包含数百万个项目,因为消耗了1-2千兆字节的内存,具体取决于填充MyData。

想要找到一个类似于Dictionary的数据结构,但我可以指定内存消耗的最大大小,如果内存已经结束,那么长时间未访问的数据会进入硬盘。 如果对象请求对象并且对象存储在硬盘驱动器上,则应将其加载到内存中。

一般情况下,我在.NET库中搜索具有此类要求的密钥/值存储。 1.我必须能够指定存储的最大RAM使用率 它应该使用磁盘进行交换。 它应该很快。

4 个答案:

答案 0 :(得分:3)

.NET中没有任何东西可以在一个预制包中完成您想要的所有操作。但是,你想要的所有组件都只需要将它们捆绑在一起。

你想要的东西有3件

  
      
  1. “想要找到一个类似于Dictionary的数据结构,但我可以指定最大内存消耗大小”
  2.   
  3. “如果内存已经结束,那么长时间未访问的数据会进入硬盘”
  4.   
  5. “如果对象请求对象并且对象存储在硬盘驱动器上,则应将其加载到内存中。”
  6.   

您所描述的是由持久性存储支持的内存缓存。

最简单的方法(没有寻找已经执行此操作的第三方库)是创建一个包含MemoryCache的类,您可以在其中设置CacheMemoryLimit。这照顾了要求#1。

当您向缓存添加项目时,您将CacheItemPolicy.RemovedCallback设置为将项目写入磁盘的功能(无论是数据库,文件还是您需要的任何内容)。这照顾了要求#2。

当您尝试从缓存中接收项目并且缓存返回.image-container { position: relative; width: 50%; } .image-overlay { width: 100%; height: 80%; border-right: 1px solid #000; } .image-with-overlay { position: relative; } (项目不在缓存中)时,您会查看该持久存储并检索该值并将其放回缓存中。这照顾了要求3.

这是一个(未经测试的)快速示例,null执行从磁盘保存和加载的逻辑。

IPersistanceProvider

答案 1 :(得分:0)

我不相信有一个原生的.net解决方案可以解决你能够在内存中存储千兆字节对象并使其可搜索,备份到磁盘和内存效率的问题。

但是有一些工具可以实现。您正在寻找的一般概念可能是Document DB(或NoSQL)。

如果你主要关注的是搜索东西,我过去就有Lucene.Net。还有很多Key / Value对工具(我没有使用任何工具,但也许其他人可以提出他们的建议)。

答案 2 :(得分:0)

如果您使用的是64位,则可能有

2a上。它应该使用磁盘进行交换

2B。它应该很快。

免费忽略先决条件。 Windows 换出未使用的内存块,然后在加载时将进行交换。因此,您可以简单地忽略内存使用,让Windows通过交换文件处理它。唯一的问题可能是你的MyData是一个“参考树”,其中一个“主”对象连接(引用)到其他对象。这些子对象中的每一个都可以位于内存的不同部分,因此可以单独交换/换出。

请注意,作为一种简单的替代方法,您可以尝试使用protobuf序列化MyData,然后使用DeflateStream在内存中压缩它,而不是byte[]原始的MyData ...显然,当需要数据时你必须做相反的事情。

答案 3 :(得分:0)

您似乎正在处理WeakReference课程要解决的一些问题。 WeakReference类不直接处理持久化对象,但根据问题的详细信息,一组不同的要求可能对您有用。

假设每个字典条目值指的是可以履行这些角色的类:

  1. 知道上次访问数据的时间;
  2. 当时间在某个阈值内时,它指的是具有强引用的数据的其余部分(常规参考);
  3. 当时间超出某个阈值时,它会将数据写入文件并将数据移至WeakReference
  4. 然后你只需要一种触发对象来检查时间的方法,可能是在低优先级的后台线程上。如果您选择适当的时间阈值,则在这种情况下,内存限制可能会自行处理。