.NET 缓存中是否有最大数量的键/元素?如果是,限制是多少?我不是指以 MB 为单位的缓存的最大大小。
1 回答
不能有一个准确的字节限制,因为它们的实现不能知道一个对象需要多少字节(可以计算出来,但不能开箱即用)。没有像“sezeofobject(reference)”这样的内置函数,因为不可能说出“对象结束”的位置。假设您有一个指向其他 3 个对象的对象,它们应该算作原始对象的一部分吗?
无论如何,尽管可以间接评估缓存解决方案需要多少内存,但不可能准确地做到这一点,例如,可以只使用反射来计算字段数并使用原始类型的 sizeof()等。但同样,这将给出一个大概的数字。
我们是如何解决这个问题的——我们序列化保存在 byte[] 中的对象——这会用一颗子弹杀死许多兔子:
- 从缓存返回的对象对 GC 来说是“不可见的”,并且不会对图遍历造成任何内存压力
- 我们可以确切地知道一个对象图需要多少字节
- 从缓存返回的对象是 100% 线程安全的副本
最大的问题是GC。
.NET 提供的缓存类很方便,但有一个主要问题——它们不能长时间存储大量对象数据(数千万以上)而不杀死你的 GC。如果您缓存几千个对象,它们会很好地工作,但是当您移动到数百万个对象并保留它们直到它们传播到 GEN2 时 - 当您的系统达到低内存阈值并且 GC 需要清除时,GC 暂停最终会开始变得明显所有的氏族。
实用性是这样的——如果你需要存储几十万个实例——使用 MS 缓存。无论您的对象是 2 字段还是 25 字段,这都与引用数量有关。
另一方面,在某些情况下,需要使用当今常见的大 RAM,即 64 GB。为此,我们创建了一个 100% 托管的内存管理器和位于其之上的缓存。
我们的解决方案可以轻松地在进程中存储 300,000,000 个对象,而无需对 GC 征税——这是因为我们将数据存储在大 (250 mb) 字节[] 段中。
这是代码:NFX Pile (Apache 2.0) https://github.com/aumcode/nfx/blob/master/Source/NFX/ApplicationModel/Pile/ICache.cs
和视频:NFX Pile Cache - Youtube