情况:
我正在处理的程序使用非常大的SQLite数据库作为数据后端(这不能更改,与问题无关)。索引以合理的方式应用,所有查询都很快完成,但请求数量也非常大。
我发现了一个特殊类型查询的主要瓶颈,它会读取一堆半静态的行:以前的任何结果都是有效的,但可能会返回其他行。可能的查询结果对的数量在"几GB"当存储为C#数据结构时。
我想到的解决方案会将此查询类型捆绑在缓存类中。它会将特定查询的所有结果存储在类似字典的结构中。已知查询将仅更新此查询的可能添加的结果子集。到目前为止没问题。
建议的解决方案:
由于缓存可能超过可用RAM,因此需要允许C#到GC一些缓存结果。合理地,应该首先清除使用最少的结果。为此,我唯一知道的唯一解决方案是WeakReferences。
因此,我认为所有低价值的结果都只能微弱地存储。然后我会对访问(或者后台线程)实施连续自检,检查删除的值,如果找到很多,则更积极地将强转换为弱引用,以允许GC声明更多。
除非压力非常高,否则这个过程会使那些被认为更有价值的结果作为强有力的参考。
问题:
我是否需要自己实现,或者是否有内置的解决方案来完成此任务或类似的任务?更一般地说:上述提案是否是一个合理的解决方案?
答案 0 :(得分:0)
来自Microsoft网站
避免使用弱引用作为内存管理问题的自动解决方案。
需要定义"可用内存"。
.NET具有对象大小限制,而Dictionary是对象
限制类似于1 GB,使用X64我认为你可以更高。
这不是一个硬限制 - 它是连续的记忆。
如果你想删除较少使用的行,它会有很多开销 清除旧的很可能是O(n)
我会追求第一个GB,看看能得到什么。
您还可以添加第二个(和第三个)字典,因为它们是单独的对象
但在某个时刻,你将无法获得连续的记忆。
我认为更好的方法是让数据库跟踪最常用的数据 然后,当您的应用程序开始下载最常用的1 GB时。