c# - 可以将访问频率较低的元素保存到磁盘的字典

标签 c# database serialization dictionary out-of-memory

在我的应用程序中,我使用字典(支持添加、删除、更新和查找),其中键和值都可以序列化或可以序列化(值可能是非常大的对象图)。当字典变得如此之大以致于将它完全保存在内存中开始偶尔触发 OutOfMemoryException(有时在字典方法中,有时在代码的其他部分)时,我遇到了一个问题。

在尝试用数据库完全取代字典后,性能下降到无法接受的水平。

对字典使用模式的分析表明,通常只有一小部分值是“热”值(经常访问),而其余部分(大部分)是“冷”值(很少或从不访问)。很难说什么时候添加新值是热值还是冷值,而且,随着时间的推移,一些值可能会在热值和冷值之间来回迁移。

我认为我需要一个字典的实现,它能够在低内存事件时将其冷值刷新到磁盘,然后根据需要重新加载其中一些并将它们保存在内存中,直到下一个低内存事件发生何时重新评估他们的热/冷状态。理想情况下,实现应根据应用程序中的内存使用情况巧妙地调整其热部分和冷部分的大小以及刷新间隔,以最大限度地提高整体性能。因为应用程序中存在多个字典实例(具有不同的键/值类型),我认为,它们可能需要协调它们的工作流。

您能否建议如何实现这样的字典?

最佳答案

为 64 位编译,在 64 位上部署,添加内存。记在心里。

在你自己成长之前,你也可以看看 WeakReference http://msdn.microsoft.com/en-us/library/ms404247.aspx .这当然需要你重建那些被回收的对象,但人们应该希望那些被回收的对象不会被太多使用。它附带一个警告,即它自己的指南声明要避免使用弱引用作为内存管理问题的自动解决方案。相反,开发一个有效的缓存策略来处理应用程序的对象。

当然,您可以忽略该准则并有效地编写代码来说明它。

您可以实现缓存策略,并在过期时保存到数据库,获取并缓存。当然要使用滑动到期,因为您关心的是保留那些最常用的。

但请记住,最常用与最重是一种权衡。每天丢失 10 次需要 5 分钟才能恢复的对象比丢失 10000 次对象而工具仅需 5 毫秒来恢复更让用户烦恼。

上面有人提到了网络缓存。如前所述,它使用回调进行自动内存管理,这取决于你是否想在你的应用程序中使用它。

还有...最后但并非最不重要的一点,看看分布式缓存。通过分片,您可以将大词典拆分到几台机器上。

关于c# - 可以将访问频率较低的元素保存到磁盘的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17776139/

相关文章:

c# - 从 ID == ID 的 DataContext 中删除的简单 LINQ 查询

c# - 删除SQL Server中的存储过程

c# - 通过 tcpclient 发送序列化对象的问题

java - 如何序列化包含对象列表的对象?

c# - 通用 FromEvent 方法

c# - P&P RetryPolicy,什么是 transient 异常

java - 用于文件写入和模拟数据库的单例与静态类

mysql - 在 MySQL 中存储 0.5

mysql - 检索聚合函数受条件约束的记录

c# - protobuf-net + Mono + Linux