2009-06-01 85 views
26

垃圾收集器可以为.NET进程分配的最大内存量是多少?当我编译为x64时,Process.GetCurrentProcess.MaxWorkingSet返回大约1,4GB,但是当我编译为AnyCPU(x64)时,将返回相同的数字。对于x64,它应该更像是任务管理器中显示的“限制”值。我如何获得正确的数字,当超出所有情况下都会导致OutOfMemory异常?.NET进程可以分配的最大内存

一些例子的方法应该返回什么:

1)机器配置:x64的Windows,4GB的物理内存,4GB页面文件
-As 64位进程:8GB
-As 32位进程:1.4GB

2)机配置:x64的Windows,1GB物理内存,2GB页面文件
-As 64位过程:3GB
-As 32位过程:1.4GB

3)机器配置:X32-的Windows,4GB的物理内存,4GB页面文件
-As 64位进程:不会发生
-As 32位进程:1.4GB

4)机器配置: X32-的Windows,512MB的物理内存,512MB的页面文件
-As 64位进程:不会发生
-As 32位进程:1.0GB

+0

这里有一篇有趣的文章,讨论.NET进程开始看到内存异常的理论最大值和范围:http://blogs.msdn.com/b/ tom/archive/2008/04/10/chat-question-memory-limits-for-32-bit-and-64-bit-processes.aspx – 2014-05-29 18:22:54

回答

3

不它取决于你有多少RAM ?

理论上,一个x64进程可以分配EB的内存(etabytes?),我认为 - 即一个LOT。但是,如果你这样做,你的机器应该开始疯狂分页,一般都会死机。

它在32位模式下是不同的,因为你不能在Windows的任何进程中分配超过1GB的内存(是的,它周围有方法,但并不漂亮)。实际上,每个.NET过程大约需要7-800meg,因为.NET保留了一些空间。

无论哪种方式,在32位中,最多可以使用3GB - 操作系统为自己保留1GB的虚拟空间。

在64位,它应该是2^64,这是一个很大的数字,但http://en.wikipedia.org/wiki/X86-64表示它是256TB的虚拟空间,以及1TB的REAL RAM。无论哪种方式,它都比你的机器中可能存在的要多得多,所以它会打到页面文件。

随着64位操作系统和一个64位的运行时, 2.0基于.NET应用程序现在可以利用 用于数据 如基于服务器的高速缓存500倍以上的存储器。

这有一些好的信息,也http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit

顺便说一句,如果你是一个64位的机器(即,64机+ x64操作系统)上,编制了AnyCPU和x64做同样的事情 - 它运行在x64模式。唯一的区别是,如果你使用AnyCPU VRS 86:

  • 64 OS/.NET,AnyCpu:64位应用程序
  • x64操作系统/。NET,64:64的应用程式
  • x64操作系统/ .NET,X32:X32应用程序(64 .NET作为Fx相BOTH x32或x64的版本安装框架)

  • X32 OS/NET,AnyCPU:X32应用程序

  • x32 OS/.NET,x64:破坏和烧伤婴儿! (实际上,它只是优雅地死去)
  • x32 OS/.NET,x32:x32应用程序。
+0

但是我怎样才能得到一台机器的真实内存限制? – Rauhotz 2009-06-01 12:15:38

+0

我标记你的答案不好,因为你混杂了一切。 3代表内存是可以存活一个或多个进程的最大可用物理内存。任何进程都可以访问完整的4个演出空间(32位地址),无法在物理内存中的内存将被缓存(如果缓存设置正确)。而3演出也不完全是真实的。你必须设置XP,默认情况下,应用程序只有2个RAM,对于OS(物理内存)只有2个RAM。 – 2011-10-26 02:02:36

17

Windows可以配置为按需分配更多页面文件空间,或on request
Job objects可以防止消耗超过一定量的内存。
碎片堆和它的代性质(加上需要投入大量的东西在大对象堆)

的所有这些意味着硬限制是不是在现实多大用处,并指回答“如何我理论上可以分配多少内存“比你想象的要复杂得多。

因为它是复杂的人这个问题可能是试图做一些事情错误,并应他们的问题重定向到更有用的东西。

你想做什么似乎需要这样一个问题?

“我只是想知道什么时候该进程的当前内存负载能拿问题 所以我可以像释放自定义缓存的一些项目的动作。”

没错。这个问题更容易处理。在复杂的顺序

两个解决方案:

  1. 让你的缓存使用WeakReferences
    • 这意味着事情会被系统几乎奇迹般地为你解脱出来,但你将拥有的东西像小控制替换策略
    • 这依赖于缓存的数据比密钥的密钥和开销都大很多
  2. 注册为notification of Garbage Collections
    • 这使您可以控制释放事物。
    • 您依赖的系统具有合适的GC代最大尺寸,可能需要一段时间才能达到稳定状态。

注意事项。 它真的确实比重新计算/重新请求数据维护这个海量缓存(通过它的声音进入磁盘)更便宜。
如果您的缓存在通常/连续请求的项目之间显示较差的位置,那么将花费很多努力来分页数据。具有有效调整的重新定位策略的较小的缓存具有显着更好的性能(并且对其他正在运行的程序的影响要小得多)

另外:在.Net中,没有可变大小的对象(字符串,数组)由于内存管理的核心CLR结构的限制,大小超过2GB。 (并且上述任一解决方案都将从中受益)