我正在测试一个收藏在.NET中的大小。从技术上讲,任何收集对象都可以生长到物理内存的大小。

然后,我在SEVER中测试了以下代码,该密码具有16GB内存,运行Windows 2003 Server和Visual Studio2008。我测试了F#和C#代码,并在运行时查看了任务管理器。我可以看到,在增长2GB内存之后,该程序崩溃了,但异常异常。我确实在属性页面中将目标平台设置为X64。

open System.Collections.Generic

let d = new Dictionary<int, int>()

for i=1 to 1000000000 do
    d.Add(i,i)

我对 C5 收集库。结果是C5中的字典可以用尽整个内存。该代码使用C5:

let d = C5.HashDictionary<int, int> ()
for i=1 to 1000000000 do
    d.Add(i,i)

有人知道为什么吗?

有帮助吗?

解决方案

Microsoft CLR具有2GB的最大对象大小限制,即使是64位版本。 (我不确定此限制是否也存在于单声道等其他实现中。)

限制适用于每个 单身的 对象 - 不是所有对象的总尺寸 - 这意味着使用某种复合集合的合成集合可以相对容易解决。

这里有讨论和一些示例代码...

似乎几乎没有官方文件指的是该限制。毕竟,这只是当前CLR的实现细节。我知道的唯一提到的是 在本页面:

当您在64位Windows操作系统上运行64位托管应用程序时,您可以创建一个不超过2 GB(GB)的对象。

其他提示

在4.5之前的.NET版本中,最大对象大小为2GB。从4.5开始,您可以分配较大的对象 gcallowverylargeobjects 已启用。请注意,极限 string 不受影响,但“数组”也应覆盖“列表”,因为列表由数组支持。

要明确,词典使用单个数组添加对。每次填满时,它都会成长(加倍?)。当有5.12亿个对象时,其尺寸为2GByte(带有32位对象指针,并假设分配完美)。添加一个元素使词典尝试再次将数组大小加倍。繁荣。

C5 Hashdictionary使用线性哈希,并且可能使用一系列包含多个(16?)元素的桶。它应该遇到相同的问题(非常多)。

“允许大物体”只会有助于摆脱OOM例外。

当一个人需要存储很多对象时,您会看到的问题是GC摊位(暂停)。我们所做的是“隐藏” GC的数据,这变成了非常实用的解决方案。

看到这个: https://www.infoq.com/articles/big-memory-part-3

您可以使用用作字典的缓存:https://github.com/aumcode/nfx/tree/master/source/nfx/applicationmodel/pile

参见缓存部分

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top