我在c#应用程序中使用Hashtable。我正在加载数百万的密钥,但是在应用程序超过3.7GB的RAM后,它给了我一个“内存不足”的例外。
我使用的是x64操作系统,而且电脑有16GB的内存。我在考虑这可能是x86的限制。我将构建类型更改为x64,但仍然出现错误。
.net中的对象是否有最大内存大小?我可以做点什么来使用所有内存吗?
谢谢, 安德鲁
答案 0 :(得分:8)
看看上一个答案:.NET Max Memory Use 2GB even for x64 Assemblies
2GB限制分别适用于每个对象。用于所有对象的总内存可能超过2GB。
答案 1 :(得分:6)
使用Dictionary<,>
代替HashTable
。在HashTable
中,键和值都是对象,因此如果它们是值类型,则它们将被装箱。 Dictionary
可以将值类型作为键和/或值,使用较少的内存。例如,如果您使用int
作为密钥,则每个将在HashTable
中使用28个字节,而在Dictionary
中仅使用4个字节。
如果键和值都是值类型且使用少于8个字节,则Dictionary
将能够容纳比HashTable
更多的项目。
答案 2 :(得分:1)
这个article表明.NET将单个对象的大小限制为2 GB。
答案 3 :(得分:1)
我发现这个页面非常有用,因为我在VB .net中遇到了完全相同的问题。我创建了一些非常大的哈希表,我的应用程序在尝试创建它们时抛出了内存异常。
我尝试了“Guffa”的想法,即在较小的示例哈希表上使用词典,结果字典实际上增加了大小!
他的建议让我想到了我实际上写给Hashtable的内容。所以我查看了这个page并决定我不需要存储长类型的数据,整数绰绰有余。我知道我可能会告诉你所有的大师那里有什么令人目眩的明显但我能够将结果序列化的hastables(总共12个)从81.9Mb减少到69.4Mb,只需将变量声明为整数而不是Longs。
这实际上并没有解决我的问题,但肯定会缩短将它们加载回内存所需的时间。
答案 4 :(得分:0)
问题与系统中物理RAM的数量无关,或者是否是x64编译。现在,.NET必须将对象限制为2GB。 (您可能需要调查.NET 4.5的大对象堆以获取有关此内容的更多信息。)您获得“内存不足”的原因是因为该进程无法映射您请求的大小的连续内存部分。
Eric Lippert在这个话题上有一个很好的blog article,我注意到他对这个问题发表了评论,但遗憾的是没有回答。
所以这就是答案:接受这样一个事实,即您使用此实现寻找的内存大小并不容易获得,并通过将其分解为更小的内存块来解决您的问题。
我有同样的问题,不得不采取相同的方法。使用锯齿状数组可能有助于将数据分解为多个逻辑组件,并创建一系列较小的HashTable。