如何在使用Visual C# 2008 Express Edition进行调试时减少已加载的dll数量?
当在调试器中运行Visual C#项目时,由于2GB虚拟地址空间的碎片化,我会遇到OutOfMemoryException异常,我们认为已加载的dll可能是碎片化的原因。
Brian Rasmussen,你让我一天都很开心! :)
他提出的“禁用Visual Studio托管进程”解决了这个问题。
(有关问题开发历史的更多信息,请参见下文)
嗨, 我需要在一个Visual C#项目中将两个大整型数组加载到内存中,每个数组都有约120万个元素(每个约470MB)。
当我尝试实例化第二个数组时,我会遇到OutOfMemoryException异常。
我确实有足够的总可用内存,并且在进行网络搜索后,我认为我的问题在于我的系统上没有足够大的连续空闲内存块。 但是! - 当我在一个Visual C#实例中实例化其中一个数组,然后打开另一个Visual C#实例时,第二个实例可以实例化大小为470MB的数组。 (编辑以澄清:在上面的段落中,我指的是在Visual C#的调试器中运行)
任务管理器显示相应的内存使用增加,就像您预期的那样。 因此,整个系统上没有足够的连续内存块不是问题。 然后我尝试运行编译后的可执行文件,它也可以实例化两个数组(内存使用1GB)
总结:
在Visual C#中使用两个大整型数组时发生了OutOfMemoryException异常,但是运行编译后的exe文件有效(内存使用量为1GB),而两个独立的Visual C#实例能够找到足够大的连续内存块来存储我的大数组,但我需要一个Visual C#实例来提供内存。
更新:
首先,特别感谢nobugz和Brian Rasmussen,我认为他们的预测“进程的2GB虚拟地址空间的分段”是问题的原因。
按照他们的建议,我使用VMMap和listdlls进行了简短的业余分析,并得到以下结果:
* “独立运行”的exe列出了21个dll(可以工作且使用1GB内存)
* vshost.exe版本列出了58个dll(在调试时运行,抛出异常且只使用500MB内存)
VMMap向我展示了调试器版本中最大的可用内存块为262,175,167,155,108MB。
因此,VMMap表示没有连续的500MB块,并根据有关可用块的信息,我添加了大约9个较小的int数组,其总计超过1.2GB内存使用量,实际上可以正常工作。
因此,从这个角度来看,“2GB虚拟地址空间的分段”是罪魁祸首。
通过listdll输出,我创建了一个小型电子表格,将十六进制数字转换为十进制以检查dll之间的空闲区域,并在(21)个dll之间找到了独立版本的大型空闲空间,但未在vshost-debugger版(58个dll)中找到。我并不认为我在那里做的事情一定正确,也不确定是否还有其他因素,但这似乎符合VMMap的分析,并且似乎dll本身就已经使调试器版本的内存发生了分段。
因此,也许解决方案是减少调试器使用的dll数量。
1.这可行吗?
2.如果可以,我该如何做?