我可以使用C#中内存使用有限的结构(字典)?
告诉我什么库(最好是纯.NET)可以用于以下问题。有字典我可以使用C#中内存使用有限的结构(字典)?,c#,memory-management,dictionary,C#,Memory Management,Dictionary,告诉我什么库(最好是纯.NET)可以用于以下问题。有字典 Dictionary < long, MyData > 字典包含数百万个条目,这是由于消耗了1-2G的内存,这取决于填充MyData 我想找到一个类似于Dictionary的数据结构,但我可以指定内存消耗的最大大小,如果内存用完,那么长时间未访问的数据就会进入硬盘。 如果对象是通过键请求的,并且对象存储在硬盘上,则应将其加载到内存中 一般来说,我在.NET库中搜索具有此类要求的键/值存储。 1.我必须能够指定存储的最大RAM使用量
2.它应该很快。我认为没有一个本机的.net解决方案可以解决您的问题,即能够在内存中存储千兆字节的对象,并使它们可以搜索、备份到磁盘和提高内存效率 但也有一些工具可以做到这一点。您正在寻找的一般概念可能是文档数据库(或NoSQL)
如果你主要关注的是让事情变得可搜索,我以前有Lucene.Net。还有很多键/值对工具(我没有使用过,但也许其他人可以提出他们的建议)。我不相信有一个本机的.net解决方案可以解决您在内存中存储千兆字节的对象并使它们可搜索、可备份到磁盘和内存效率高的问题 但也有一些工具可以做到这一点。您正在寻找的一般概念可能是文档数据库(或NoSQL)
如果你主要关注的是让事情变得可搜索,我以前有Lucene.Net。还有很多键/值对工具(我没有使用过,但也许其他人可以提出他们的建议)。我不相信有一个本机的.net解决方案可以解决您在内存中存储千兆字节的对象并使它们可搜索、可备份到磁盘和内存效率高的问题 但也有一些工具可以做到这一点。您正在寻找的一般概念可能是文档数据库(或NoSQL)
如果你主要关注的是让事情变得可搜索,我以前有Lucene.Net。还有很多键/值对工具(我没有使用过,但也许其他人可以提出他们的建议)。我不相信有一个本机的.net解决方案可以解决您在内存中存储千兆字节的对象并使它们可搜索、可备份到磁盘和内存效率高的问题 但也有一些工具可以做到这一点。您正在寻找的一般概念可能是文档数据库(或NoSQL)
如果你主要关注的是让事情变得可搜索,我以前有Lucene.Net。还有很多键/值对工具(我没有使用过任何工具,但也许其他人可以提出他们的建议)。如果您使用的是64位,您可能需要 2a。它应该使用磁盘进行交换 2b。应该很快 免费忽略先决条件。Windows将交换未使用的内存块,然后在加载这些内存块时进行交换。因此,您可以简单地忽略内存使用,让Windows通过交换文件来处理它。唯一的问题可能是,如果您的
MyData
是一个“引用树”,其中一个“主”对象连接(引用)到其他对象。这些子对象中的每一个子对象都可以位于内存的不同部分,因此可以分别进行换入/换出
请注意,作为一种简单的替代方法,您可以尝试使用
protobuf
对MyData
进行序列化,然后使用DeflateStream
在内存中对其进行压缩,保留一个byte[]
而不是原始的MyData
。。。显然,当需要数据时,您必须执行相反的操作。如果您使用的是64位,您可能需要
2a。它应该使用磁盘进行交换
2b。应该很快
免费忽略先决条件。Windows将交换未使用的内存块,然后在加载这些内存块时进行交换。因此,您可以简单地忽略内存使用,让Windows通过交换文件来处理它。唯一的问题可能是,如果您的MyData
是一个“引用树”,其中一个“主”对象连接(引用)到其他对象。这些子对象中的每一个子对象都可以位于内存的不同部分,因此可以分别进行换入/换出
请注意,作为一种简单的替代方法,您可以尝试使用
protobuf
对MyData
进行序列化,然后使用DeflateStream
在内存中对其进行压缩,保留一个byte[]
而不是原始的MyData
。。。显然,当需要数据时,您必须执行相反的操作。如果您使用的是64位,您可能需要
2a。它应该使用磁盘进行交换
2b。应该很快
免费忽略先决条件。Windows将交换未使用的内存块,然后在加载这些内存块时进行交换。因此,您可以简单地忽略内存使用,让Windows通过交换文件来处理它。唯一的问题可能是,如果您的MyData
是一个“引用树”,其中一个“主”对象连接(引用)到其他对象。这些子对象中的每一个子对象都可以位于内存的不同部分,因此可以分别进行换入/换出
请注意,作为一种简单的替代方法,您可以尝试使用
protobuf
对MyData
进行序列化,然后使用DeflateStream
在内存中对其进行压缩,保留一个byte[]
而不是原始的MyData
。。。显然,当需要数据时,您必须执行相反的操作。如果您使用的是64位,您可以
public interface IPersistanceProvider<TValue>
{
void Save(string key, TValue value);
TValue Load(string key);
}
public sealed class CustomCache<TValue> : IDisposable
where TValue: class
{
private readonly TimeSpan _slidingExpirationWindow;
private readonly IPersistanceProvider<TValue> _persistanceProvider;
private readonly MemoryCache _cache;
/// <summary>
/// A custom cache that writes items out to a IPersistanceProvider when the item is evicted from the cache.
/// </summary>
/// <param name="slidingExpirationWindow">The amount of time before the item is automatically evicted if it has not been accessed.</param>
/// <param name="cacheMemoryLimitMegabytes">The maximum size the cache can be before it starts force evicting items.</param>
/// <param name="persistanceProvider">The service that will save and load data to a persistent storage.</param>
public CustomCache(TimeSpan slidingExpirationWindow, int cacheMemoryLimitMegabytes, IPersistanceProvider<TValue> persistanceProvider)
{
_slidingExpirationWindow = slidingExpirationWindow;
_persistanceProvider = persistanceProvider;
_cache = new MemoryCache("", new NameValueCollection { { "CacheMemoryLimitMegabytes", cacheMemoryLimitMegabytes.ToString("D") } });
}
public void SetItem(string key, TValue value)
{
if (key == null)
throw new ArgumentNullException("key");
if (value == null)
throw new ArgumentNullException("value");
SetCacheItem(key, value);
}
public TValue GetItem(string key)
{
if (key == null)
throw new ArgumentNullException("key");
var item = _cache.Get(key);
if (item == null)
{
item = _persistanceProvider.Load(key);
SetCacheItem(key, item);
}
return (TValue)item;
}
public void RemoveItem(string key)
{
if (key == null)
throw new ArgumentNullException("key");
_cache.Remove(key);
}
public void Dispose()
{
if (_cache != null)
{
_cache.Dispose();
}
}
private void SetCacheItem(string key, object value)
{
var policy = new CacheItemPolicy();
policy.RemovedCallback = RemovedCallback;
policy.SlidingExpiration = _slidingExpirationWindow;
_cache.Set(key, value, policy);
}
private void RemovedCallback(CacheEntryRemovedArguments arguments)
{
if (arguments.RemovedReason == CacheEntryRemovedReason.Removed)
return;
_persistanceProvider.Save(arguments.CacheItem.Key, (TValue)arguments.CacheItem.Value);
}
}