.NET 进程可以分配的最大内存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/934314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maximum Memory a .NET process can allocate
提问by Rauhotz
What is the maximum memory the garbage collector can allocate for a .NET process? When i compile to x64, Process.GetCurrentProcess.MaxWorkingSet returns about 1,4GB, but when i compile to AnyCPU (x64) the same number is returned. For x64 it should be more like the "Limit" value that is displayed in the Task Manager. How can i get the correct number that will cause OutOfMemory-Exceptions when exceeded in all cases?
垃圾收集器可以为 .NET 进程分配的最大内存是多少?当我编译到 x64 时,Process.GetCurrentProcess.MaxWorkingSet 返回大约 1.4GB,但是当我编译到 AnyCPU (x64) 时返回相同的数字。对于 x64,它应该更像是任务管理器中显示的“限制”值。如何获得在所有情况下超过时会导致 OutOfMemory-Exceptions 的正确数字?
Some examples what the method should return:
方法应该返回的一些示例:
1) Machine Configuration: x64-Windows, 4GB physical memory, 4GB page file
-As 64-Bit process: 8GB
-As 32-Bit process: 1.4GB
1)机器配置:x64-Windows,4GB物理内存,4GB页面文件
-As 64-Bit process:8GB
-As 32-Bit process:1.4GB
2) Machine Configuration: x64-Windows, 1GB physical memory, 2GB page file
-As 64-Bit process: 3GB
-As 32-Bit process: 1.4GB
2)机器配置:x64-Windows,1GB物理内存,2GB页面文件
-As 64-Bit process:3GB
-As 32-Bit process:1.4GB
3) Machine Configuration: x32-Windows, 4GB physical memory, 4GB page file
-As 64-Bit process: Won't happen
-As 32-Bit process: 1.4GB
3)机器配置:x32-Windows,4GB物理内存,4GB页面文件
-As 64-Bit process:不会发生
-As 32-Bit process:1.4GB
4) Machine Configuration: x32-Windows, 512MB physical memory, 512MB page file
-As 64-Bit process: Won't happen
-As 32-Bit process: 1.0GB
4)机器配置:x32-Windows,512MB物理内存,512MB页面文件
-As 64-Bit process:不会发生
-As 32-Bit process:1.0GB
回答by ShuggyCoUk
Windows can be configured to allocate more page file space on demand, or on request.
Job objectscan prevent the consumption of more than a certain amount of memory.
Fragmentation of the heap and the generational nature of it (plus the need to put large stuff in the Large Object Heap)
Windows可以被配置为按需分配多页的文件空间,或根据要求。
作业对象可以防止消耗超过一定数量的内存。
堆的碎片和它的分代性质(加上需要将大的东西放在大对象堆中)
All these mean that the hard limit is not much use in reality and means answering the question "how much memory could I theoretically allocate" is rather more complex than you think.
所有这些都意味着硬限制在现实中并没有多大用处,并且意味着回答“理论上我可以分配多少内存”的问题比您想象的要复杂得多。
Since it is complex anyone askingthat question is probably trying to do something wrongand should redirect their question to something more useful.
由于它是复杂的人问这个问题可能是试图做一些错误的,并应他们的问题重定向到更有用的东西。
What are you trying to do that would appear to necessitate such a question?
你想做什么似乎需要这样一个问题?
"I just want to know when the current memory load of the process could get problematic so I can take actions like freeing some items of a custom cache."
“我只想知道进程的当前内存负载何时会出现问题,以便我可以采取一些措施,例如释放自定义缓存的某些项目。”
Right. this is much more tractable a question.
对。这是一个更容易处理的问题。
Two solutions in order of complexity:
按复杂程度排序的两种解决方案:
- Make your caches use WeakReferences
- This means that things will be freed by the system almost magically for you but you will have little control over things like the replacement policy
- this relies on the cached data being much bigger than the key and the overhead of a weak reference
- Register for notification of Garbage Collections
- This lets you take control of freeing things up.
- you rely on the system having the appropriate maximum size for the GC generations which may take a while to get to a steady state.
- 让你的缓存使用WeakReferences
- 这意味着系统几乎会神奇地为您释放东西,但您几乎无法控制诸如更换政策之类的东西
- 这依赖于比键大得多的缓存数据和弱引用的开销
- 注册垃圾收集通知
- 这使您可以控制释放事物。
- 您依赖于具有适合 GC 生成的最大大小的系统,这可能需要一段时间才能达到稳定状态。
Points to note.
Is it reallyless expensive to maintain this massive cache (going to disk by the sounds of it) than to recalculate/re-request the data.
If your cache exhibits poor locality between commonly/consecutively requested items then much effort will be spent paging data in and out. A smaller cache with an effective tuned relpacement policy stands a good chance of performing considerably better (and with much less impact on other running programs)
注意事项。难道真的不太昂贵的维护这个庞大的高速缓存比重新计算/重新请求的数据(通过它的声音会到磁盘)。
如果您的缓存在通常/连续请求的项目之间表现出较差的局部性,那么将花费大量精力将数据分页进出。具有有效调整的 relpacement 策略的较小缓存很有可能表现得更好(并且对其他正在运行的程序的影响要小得多)
As an aside: In .Net, no variable sized object (strings, arrays) can be more than 2GB in size due to limitations of the core CLR structures for memory management. (and either solution above will benefit from this)
顺便说一句:在 .Net 中,由于用于内存管理的核心 CLR 结构的限制,任何大小可变的对象(字符串、数组)的大小都不能超过 2GB。(以上任一解决方案都将从中受益)
回答by Nic Wise
Doesn't it depend on how much RAM you have?
这不取决于你有多少内存?
In theory, a x64 process can allocate EB's (etabytes?) of RAM, I think - ie, a LOT. But if you do, your machine should start paging like crazy and generally die.
理论上,我认为 x64 进程可以分配 EB(etabytes?)的 RAM,即很多。但是如果你这样做了,你的机器应该会疯狂地开始分页并且通常会死掉。
It was different in 32 bit mode, as you couldn't allocate more than 1GB of RAM in ANY process in windows (yes, there are ways around it, but it's not pretty). In practice, this ment about 7-800meg per .NET process, as .NET reserved some space.
它在 32 位模式下是不同的,因为你不能在 Windows 的任何进程中分配超过 1GB 的 RAM(是的,有办法解决它,但它并不漂亮)。实际上,每个 .NET 进程大约需要 7-800meg,因为 .NET 保留了一些空间。
Either way, in 32 bit, the most you can use is 3GB - the OS reserves 1GB of virtual space for itself.
无论哪种方式,在 32 位中,您最多可以使用 3GB - 操作系统为自己保留 1GB 的虚拟空间。
In 64 bit, it should be 2^64, which is a big number, but http://en.wikipedia.org/wiki/X86-64says it's 256TB of virtual space, and 1TB of REAL RAM. Either way, it's a lot more than you are likely to have in your machine, so it's going to hit the page file.
在 64 位中,它应该是 2^64,这是一个很大的数字,但是http://en.wikipedia.org/wiki/X86-64说它是 256TB 的虚拟空间和 1TB 的真实 RAM。无论哪种方式,它都比您的机器中可能拥有的要多得多,因此它将访问页面文件。
With a 64-bit OS and a 64-bit runtime, .NET 2.0-based applications can now utilize 500 times more memory for data such as server-based caches.
借助 64 位操作系统和 64 位运行时,基于 .NET 2.0 的应用程序现在可以将 500 倍的内存用于数据,例如基于服务器的缓存。
This has some good info, too http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit
这也有一些很好的信息http://www.theserverside.net/tt/articles/showarticle.tss?id=NET2BMNov64Bit
BTW, if you are on a x64 machine (ie, x64 machine + x64 OS), compiling for AnyCPU and x64 does the same thing - it runs in x64 mode. The only difference is if you use AnyCPU vrs x86:
顺便说一句,如果您在 x64 机器上(即 x64 机器 + x64 操作系统),为 AnyCPU 和 x64 编译会做同样的事情 - 它在 x64 模式下运行。唯一的区别是如果您使用 AnyCPU vrs x86:
- x64 OS/.NET, AnyCpu: x64 app
- x64 OS/.NET, x64: x64 app
x64 OS/.NET, x32: x32 app (x64 .NET framework as BOTH x32 and x64 versions of the Fx installed)
x32 OS/NET, AnyCPU: x32 app
- x32 OS/.NET, x64: CRASH AND BURN BABY! (actually, it just dies gracefully)
- x32 OS/.NET, x32: x32 app.
- x64 操作系统/.NET,AnyCpu:x64 应用程序
- x64 操作系统/.NET,x64:x64 应用程序
x64 OS/.NET、x32:x32 应用程序(x64 .NET 框架作为安装的 Fx 的 x32 和 x64 版本)
x32 OS/NET,AnyCPU:x32 应用程序
- x32 操作系统/.NET、x64:崩溃并烧毁宝贝!(实际上,它只是优雅地死去)
- x32 操作系统/.NET、x32:x32 应用程序。

