当仍有大量可用内存时,抛出“System.OutOfMemoryException”异常。

120

以下是我的代码:

int size = 100000000;
double sizeInMegabytes = (size * 8.0) / 1024.0 / 1024.0; //762 mb
double[] randomNumbers = new double[size];

异常: 引发了类型为“System.OutOfMemoryException”的异常。

我的机器有4GB内存,其中2.5GB可用,当我开始运行时,显然PC上有足够的空间来处理1亿个随机数中的762MB。我需要尽可能多地存储随机数,以便利用可用内存。在生产环境中,该计算机将拥有12GB内存,我希望能够利用它。

CLR是否限制了我默认的最大内存?如何请求更多内存?

更新

如果问题是由于内存碎片化引起的,我认为将其分成较小的块并逐步增加内存需求会有所帮助,但事实并非如此。无论我如何调整块大小,我都无法超过总ArrayList大小256MB

private static IRandomGenerator rnd = new MersenneTwister();
private static IDistribution dist = new DiscreteNormalDistribution(1048576);
private static List<double> ndRandomNumbers = new List<double>();

private static void AddNDRandomNumbers(int numberOfRandomNumbers) {
    for (int i = 0; i < numberOfRandomNumbers; i++) {
      ndRandomNumbers.Add(dist.ICDF(rnd.nextUniform()));                
  }
}

从我的主方法:

int blockSize = 1000000;

while (true) {
  try
  {
    AddNDRandomNumbers(blockSize);                    
  }
  catch (System.OutOfMemoryException ex)
  {
    break;
  }
}            
double arrayTotalSizeInMegabytes = (ndRandomNumbers.Count * 8.0) / 1024.0 / 1024.0;

7
我建议重新设计你的应用程序,这样你就不必使用那么多的内存。你在做什么事情,需要一次性在内存中保存一亿个数字吗? - Eric Lippert
2
你没有禁用页面文件或者做了什么傻事吧? - jalf
@EricLippert,我在解决P vs. NP问题(http://www.claymath.org/millenium-problems/p-vs-np-problem)时遇到了这个问题。您有减少工作内存使用的建议吗?(例如,将数据块序列化并存储在硬盘上,使用C++数据类型等) - devinbost
@bosit 这是一个问答网站。如果您有关于实际代码的具体技术问题,请将其发布为问题。 - Eric Lippert
@bostIT,你在评论中提供的P vs. NP问题链接已经失效了。 - RBT
更新的链接:P vs. NP 问题 - devinbost
14个回答

0
如果您不需要使用Visual Studio托管进程:
请取消选中以下选项:项目->属性->调试->启用Visual Studio托管进程
然后进行构建。
如果仍然遇到问题:
请前往项目->属性->生成事件->后期生成事件命令行,并粘贴以下内容:
call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)"  /LARGEADDRESSAWARE

现在,构建项目。


0

我曾经遇到过类似的问题,那是由于使用了 StringBuilder.ToString() 方法导致的。


不要让 StringBuilder 变得太大。 - Ricardo Rix

0

我有一个类似的问题,处理大数据集并试图强制应用程序使用这么多数据并不是正确的选项。我能给你的最佳建议是,如果可能的话,将数据分成小块进行处理。因为处理如此多的数据,问题迟早会再次出现。而且,你无法知道每台运行你的应用程序的机器的配置,所以总是存在异常在另一台电脑上发生的风险。


实际上我知道这台机器的配置,它只在一台服务器上运行,我可以为这些规格编写代码。这是用于大规模蒙特卡罗模拟,我正在尝试通过预先缓冲随机数来进行优化。 - m3ntat

-2
将Windows进程限制增加至3GB(通过boot.ini或Vista启动管理器)。

真的吗?默认的最大进程内存是多少?如何更改?如果我在电脑上玩游戏或其他应用程序,单个EXE/进程很容易使用2GB以上的内存,我不认为这是问题所在。 - m3ntat
/3GB 对此来说过于浪费,会导致很多不稳定性问题,因为许多驱动程序假定用户空间指针总是指向较低的2GB。 - jalf
1
m3ntat: 不,在32位Windows中,单个进程的限制是2GB。地址空间的剩余2GB由内核使用。 - jalf
即使使用PAE技术呢?http://www.microsoft.com/whdc/system/platform/server/PAE/PAEdrv.mspx - m3ntat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接