C#增加堆大小 – 是否可能

在读取大量文件时,使用C#时出现内存不足exception

我需要更改代码但是暂时可以增加堆大小(就像我在Java中一样)作为一个shaort术语修复?

.Net自动完成。

看起来你已经达到了一个.Net进程可以用于其对象的内存限制(在32位机器上,这是2个标准或3GB,使用/ 3GB启动开关。信用Leppie和Eric Lippert获取信息)。

重新思考您的算法,或者更改64位计算机可能会有所帮助。

不,这是不可能的。 可能会出现此问题,因为您在32位操作系统上运行并且内存过于分散。 尽量不要将整个文件加载到内存中(例如,通过逐行处理),或者,当您确实需要完全加载它时,将其加载到多个较小的部分中。

不,你在这里看不到我的答案: 有没有办法在.NET运行时预先分配堆,比如Java中的-Xmx / -Xms?

对于读取大文件,通常最好从磁盘中流式传输,以块的forms读取它们并一次处理它们,而不是预先加载整个文件。

正如其他人已经指出的那样,这是不可能的。 .NET运行时代表应用程序处理堆分配。

根据我的经验,.NET应用程序通常会遇到OOM,因为应该有足够的可用内存(或者至少是这样)。 其原因通常是使用巨大的集合,如数组,List(使用数组来存储其数据)或类似的集合。

问题是这些类型有时会在内存使用中产生高峰。 如果无法遵守这些峰值请求,则抛出OOMexception。 例如,当List需要增加其容量时,它通过分配当前大小的两倍的新数组然后将所有引用/值从一个数组复制到另一个数组来实现。 类似于ToArray之类的操作会生成数组的新副本。 我也看到了大型LINQ操作的类似问题。

每个数组都存储为连续内存,因此为了避免OOM,运行时必须能够获得一大块内存。 由于DLL加载和堆的一般使用,进程的地址空间可能会碎片化,因此在这种情况下抛出OOMexception并不总是可行的。

你在处理什么样的文件?

你可能最好使用StreamReader并返回ReadLine结果,如果是文本的话。

当然,你会保持一个文件指针,但最糟糕的情况是大大减少。

二进制文件有类似的方法,例如,如果要将文件上传到SQL,则可以读取byte []并使用Sql Pointer机制将缓冲区写入blob的末尾。