【问题标题】:Is there a memory limit for a single .NET process单个 .NET 进程是否有内存限制
【发布时间】:2010-09-17 01:16:23
【问题描述】:

我们目前正在考虑构建一个缓存系统来保存从 SQL 数据库中提取的数据,并使其可用于其他几个应用程序(网站、Web 服务等)。我们想象缓存作为 Windows 服务运行,并且基本上由一个保存缓存条目的智能字典组成。我的问题是,应用程序的工作集是否有限制(它将在 windows server 2003 下运行)?还是物理内存的数量有限制?

【问题讨论】:

  • 在编写第一行代码之前,请考虑您的缓存过期策略。这很难在以后烘烤。我认为您有充分的理由想要这样做,例如离线访问。性能不是一个足够好的理由,你可能会因为本地机器上的内存开销而使性能变差。
  • 实际上,性能是原因之一。第二个是我们想要集中缓存以使其可以被各种在线和离线应用程序访问。你有构建缓存系统的经验吗?你能推荐进一步阅读吗?
  • ASP.NET 缓存系统可能是获得一些想法的好地方,或者缓存应用程序块:msdn.microsoft.com/en-us/library/cc309502.aspx

标签: .net memory .net-3.5 process limit


【解决方案1】:

32 位还是 64 位? 32 位是 2gb(对于一个进程),64 位是1TB (enterprise edition 2003 server)

However, the maximum size of a CLR Object is 2gb 甚至在 64 位上。

更新:以上信息在 2008 年是正确的。请参阅Ohad's answer 了解更多最新信息。 Windows 2016 服务器最多可以有24TB

【讨论】:

  • 它与运行时的 2.0 版本相关,但我认为它在 3.5 中没有改变。无论如何,拥有一个 2gb 的对象(除非它是一个字节数组)是相当不寻常的 - 在你的情况下,它会是一个 N 大小的对象列表,所以你会没事的。
  • 限制在 .NET 4 中也是一样的。
  • 根据我的经验,即使理论上上限是 2 GB,一旦达到 1.2 GB 左右,系统就会变得不稳定。
  • 实际上,一个 32 位进程在 x86 操作系统下最多可以有 3GB,在 x64 操作系统下最多可以有 4GB。请参阅下面的答案或msdn.microsoft.com/en-us/library/…
  • 大对象限制在数值应用程序中经常发生,因为数据通常由数组支持,而数组是 .NET 中的 CLR 对象。 .NET 4.5 中取消了限制。最后! centerspace.net/blog/large-matrices-and-vectors
【解决方案2】:

我最近在 .NET 中对 32 位进程的内存限制进行了广泛的分析。我们都被我们可以在 .NET 应用程序中分配多达 2.4GB (2^31) 的想法轰炸了,但不幸的是,这不是真的 :(。应用程序进程有这么多的空间可以使用,并且操作系统做得很好然而,为我们管理它的工作,.NET 本身似乎有自己的开销,对于推动内存限制的典型现实世界应用程序来说,这大约占 600-800MB。这意味着,一旦您分配一个整数数组,大约需要1.4GB,您应该会看到 OutOfMemoryException()。

显然,在 64 位中,这个限制发生得更晚(让我们在 5 年后聊聊 :)),但由于字长增加,内存中所有内容的一般大小也会增长(我发现它是 ~1.7 到 ~2 倍) .

我可以肯定的是,操作系统的虚拟内存理念绝对不会在一个进程中为您提供几乎无限的分配空间。只有这样才能将全部 2.4GB 的空间分配给同时运行的所有(许多)应用程序。

【讨论】:

  • 我无法确认,但根据我的测试,如果真的是真的。
  • 在我们的例子中,我们使用 .NET dll 作为 IE 的插件。我们还看到 IE 在大约 1.2 GB 时抛出 OOM 异常(当我们使用插件时)。 @Luke Machowski,你能告诉我你在 .NET 还是 IE 上使用哪个内存分析工具?
  • @SandeepKhantwal 不久前,但我当时正在使用 Ants Profiler。
【解决方案3】:

MSDN 中的下表是您查询的最准确答案。请注意,不能直接从托管编译器设置 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志,但幸运的是它可以在构建后设置via the editbin utility。 4GT 指的是 /3gb 标志。

【讨论】:

    【解决方案4】:

    马蒂亚斯,

    实际上不是直接问题的答案,而是解决此问题的另一种方法,它可以绕过一些大陷阱,这对于缓存解决方案来说可能是一个令人头疼的问题。 (对不起,我没有任何关于这件事的推荐阅读。)

    我们在之前的项目中实现了这一点,但它确实产生了其他问题。

    对于离线访问,您可以在桌面上使用 sql express 来创建数据库的镜像(或者只是您需要缓存的部分)吗?然后您需要做的就是切换您的应用程序指向的数据库。您甚至可以使用它存储差异并将它们重播到服务器 - 尽管这还有其他问题。您可以更改本地副本的权限,使其成为只读副本。

    您正在考虑创建的字典听起来非常像 Sql 索引。如果你能以这种方式构建它,我会依靠 sql 为你完成这项工作。为什么要重新发明那个轮子?如果这样做,您将不得不仔细考虑缓存过期和内存管理 - 特别是如果这是 Windows 服务。

    祝你好运,

    山姆

    【讨论】:

      【解决方案5】:

      在 32 位 Windows 上,您可以通过使用 /3gb 标志启动 Windows 并将您的应用标记为“大地址感知”来获得更多内存

      【讨论】:

      【解决方案6】:

      与任何其他 Windows 程序一样,您也受到地址空间的限制。即:在 32 位上,您可以拥有 2GB 的地址空间。在 x64 上,您可以拥有 8TB。

      如果你没有 8TB 的物理内存,它将开始分页。

      【讨论】:

      • 如果您没有 8TB 的可用硬盘空间(我希望),那么您将开始出现 OutOfMemoryException。太糟糕了。不过,我们中的许多人在我们的开发机器中拥有这么大的 HDD 还需要一段时间。 :(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 2015-10-09
      相关资源
      最近更新 更多