虚拟和物理内存/ OutOfMemoryException

我正在开发一个64位的.Net Windows服务应用程序,它实际上会加载一堆数据进行处理。 在执行数据量测试时,我们能够压倒该进程并抛出OutOfMemoryException(当它失败时我没有关于进程的任何性能统计信息。)我很难相信该进程请求了一大块内存自从在64位计算机上运行以来,已超出该进程的允许地址空间。 我知道该进程正在一台机器上运行,该机器一直在80%-90%的物理内存使用率附近。 我的问题是:如果机器的可用物理内存严重不足,CLR是否会抛出OutOfMemoryException,即使进程不会超过其允许的虚拟内存量?

谢谢你的帮助!

在64位环境中仍然存在一些可达到的限制。 查看此页面了解一些最常见的内容。 简而言之,是的,如果您的程序将高达128GB的数据加载到虚拟内存中,您仍然可能会耗尽内存。 如果您没有设置IMAGE_FILE_LARGE_ADDRESS_AWARE环境变量,您仍然可能受限于每个进程2GB的最大限制。

另一种可能性是该程序试图分配一个大于2千兆字节的内存块,这是一个.NET限制。 将事物添加到集合(通常是DictionaryHashSet ,还有List或任何其他自动增长的集合)时会发生这种情况。

如果你试图将超过4700万个项目放入集合中, DictionaryHashSet会经常这样做。 尽管该集合可以容纳大约8950万,但是增加集合的算法通过加倍来实现。 如果从空Dictionary开始并开始添加项目,则集合会翻倍,直到达到大约4700万。 然后它再次尝试加倍并抛出OutOfMemoryException

避免exception的方法是预先分配集合,使其容量足够大,以容纳您希望放入其中的许多项目。

你理论上可以解决这个问题。

这就是你拥有的物理特性,当你超过开始使用swap时,这通常仅限于某些选定磁盘分区的大小。

根据经验,人们倾向于将少量(如一个或两个)物理内存的倍数作为交换。

所以是的,很可能你没有可用,而不是可寻址的内存。