c# - 字典计数大于 89478457 时出错

标签 c# .net-core .net-core-rc2

我正在执行此命令

Dictionary<UInt64, int> myIntDict = new Dictionary<UInt64, int>(89478458);

这个错误:

System.OutOfMemoryException was unhandled  HResult=-2147024882
Message=Array dimensions exceeded supported range.
Source=mscorlib
StackTrace:
   at System.Collections.Generic.Dictionary`2.Initialize(Int32 capacity)
   at System.Collections.Generic.Dictionary`2..ctor(Int32 capacity, IEqualityComparer`1 comparer)

在 89478457 上没有错误。这是 Dictionary.cs 中初始化的来源:

    private void Initialize(int capacity)
    {
        int size = HashHelpers.GetPrime(capacity);
        ...
        entries = new Entry[size];
        ...
    }

当我重现这个时,错误发生在数组创建上。在这种情况下,Entry 是一个大小为 24 的结构。当我们得到 max int32 (0x80000000-1) 并除以 24 = 89478485 并且这个数字介于素数 89478457 和 89478503 之间时。

这是否意味着结构数组不能像 maxInt32/sizeOfThisStruct 一样大?

编辑:

是的。我实际上超过 2 GB。当字典创建 struct Entry 的内部数组时,会发生这种情况,(键,值)对存储在哪里。在我的例子中,sizeof(Entry) 是 24 字节,并且作为值类型是内联分配的。

解决方法是使用 gcAllowVeryLargeObjects标志(谢谢 Evk)。实际上在 .net 核心中,标志是 the environment variable COMPlus_gcAllowVeryLargeObjects(谢谢 svick)。

是的,Paparazzi是正确的。我得想一想,如何不浪费内存。 谢谢你们。

最佳答案

.NET 运行时存在已知限制 - 堆上允许的最大对象大小为 2 GB,即使在 64 位版本的运行时也是如此。但是,从 .NET 4.5 开始有 configuration option这允许您放宽此限制(仅在运行时的 64 位版本上)并创建更大的数组。要启用的配置示例是:

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

关于c# - 字典计数大于 89478457 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37530383/

相关文章:

entity-framework-core - .Net Core Entity Framework MySQL - 字符串字段仅存储 255 个符号

asp.net - .NET Core RC2 applicationhost.config 与 ASP.NET .NET 4.6 不兼容?

asp.net-mvc - 在 IIS 中部署 .NET Core RC2 时出现服务器错误 502

c# - 构造函数字符串参数与 Ninject 的基于约定的绑定(bind)

c# - 具有可变数量参数的匿名方法

c# - 我们如何在将文件上传到 asp.net 之前检查文件类型?

c# - 有没有更好的方法将点路径作为字符串获取?

authentication - 如何实现Office 365 OAuth2登录认证的跨域请求?

authentication - 鉴于下面描述的错误,人们如何在 Ubuntu/Docker 上的 ASP.NET Core Web API 中进行身份验证?

docker - 在定义的端口上运行 RC2 项目