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

时间:2010-02-24 10:55:06

标签: c#

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

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

5 个答案:

答案 0 :(得分:7)

.Net自动完成。

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:2)

不,你不能在这里看到我的答案:Is there any way to pre-allocate the heap in the .NET runtime, like -Xmx/-Xms in Java?

对于读取大文件,通常最好从磁盘中流式传输它们,然后一块一块地读取它们,而不是预先加载整个文件。

答案 3 :(得分:2)

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

根据我的经验,当应该有足够的可用内存时(或者至少看起来如此),.NET应用程序通常会受到OOM的影响。这样做的原因通常是使用大型集合,如数组,List(使用数组来存储数据)或类似的。

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

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

答案 4 :(得分:0)

你在处理什么样的档案?

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

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

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