我的内存是4G物理,但即使我只创建1.5G内存对象,为什么我的内存异常.有什么想法吗?(我在同一时间看到,在任务管理器的性能选项卡中,内存未被完全占用,我也可以在这里输入 - 所以内存实际上并不低,所以我认为我遇到了其他一些内存限制)?
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestBigMemoryv1 { class MemoryHolderFoo { static Random seed = new Random(); public Int32 holder1; public Int32 holder2; public Int64 holder3; public MemoryHolderFoo() { // prevent from optimized out holder1 = (Int32)seed.NextDouble(); holder2 = (Int32)seed.NextDouble(); holder3 = (Int64)seed.NextDouble(); } } class Program { static int MemoryThreshold = 1500; //M static void Main(string[] args) { int persize = 16; int number = MemoryThreshold * 1000 * 1000/ persize; MemoryHolderFoo[] pool = new MemoryHolderFoo[number]; for (int i = 0; i < number; i++) { pool[i] = new MemoryHolderFoo(); if (i % 10000 == 0) { Console.Write("."); } } return; } } }
JaredPar.. 40
在普通的32位Windows应用程序中,该进程只有2GB的可寻址内存.这与可用的物理内存量无关.
所以2GB可用,但1.5是你可以分配的最大值.关键是您的代码不是该过程中运行的唯一代码.另一个.5 GB可能是CLR加上碎片的过程.
更新:在64位进程的.Net 4.5中,如果启用了gcAllowVeryLargeObjects设置,则可以使用大型数组:
在64位平台上,启用总大小超过2千兆字节(GB)的阵列.数组中的最大元素数是UInt32.MaxValue.
不,每个进程都可以获得完全可映射的2 GB虚拟内存空间. (4认同)
Marc Gravell.. 10
除了其他要点之外; 如果你想访问脏内存,请考虑x64 - 但要注意最大单个对象大小仍然是2GB.并且因为x64中的引用较大,这意味着您实际上为引用类型获得了较小的最大数组/列表大小.当然,当你达到这个极限时,你可能还是做错了!
其他选择:
使用文件
使用数据库
(显然,与进程内存相比,两者都有性能差异)
更新:在4.5之前的.NET版本中,最大对象大小为2GB.从4.5开始,如果启用了gcAllowVeryLargeObjects,则可以分配更大的对象.请注意,限制string
不受影响,但"数组"也应涵盖"列表",因为列表由数组支持.
在普通的32位Windows应用程序中,该进程只有2GB的可寻址内存.这与可用的物理内存量无关.
所以2GB可用,但1.5是你可以分配的最大值.关键是您的代码不是该过程中运行的唯一代码.另一个.5 GB可能是CLR加上碎片的过程.
更新:在64位进程的.Net 4.5中,如果启用了gcAllowVeryLargeObjects设置,则可以使用大型数组:
在64位平台上,启用总大小超过2千兆字节(GB)的阵列.数组中的最大元素数是UInt32.MaxValue.
除了其他要点之外; 如果你想访问脏内存,请考虑x64 - 但要注意最大单个对象大小仍然是2GB.并且因为x64中的引用较大,这意味着您实际上为引用类型获得了较小的最大数组/列表大小.当然,当你达到这个极限时,你可能还是做错了!
其他选择:
使用文件
使用数据库
(显然,与进程内存相比,两者都有性能差异)
更新:在4.5之前的.NET版本中,最大对象大小为2GB.从4.5开始,如果启用了gcAllowVeryLargeObjects,则可以分配更大的对象.请注意,限制string
不受影响,但"数组"也应涵盖"列表",因为列表由数组支持.
只是添加到之前的回复:您可以超越使用/ 3Gb [和可选的userva]启动标志启动的系统的2Gb限制.
检查您是否正在构建64位进程,而不是32位进程,这是Visual Studio的默认编译模式.为此,右键单击您的项目,属性 - >构建 - >平台目标:x64.与任何32位进程一样,32位编译的Visual Studio应用程序的虚拟内存限制为2GB.
每个进程都有自己的虚拟内存,称为地址空间,它会映射它执行的代码和它操作的数据.32位进程使用32位虚拟内存地址指针,它为32位进程可以处理的虚拟内存量创建4GB(2 ^ 32)的绝对上限.但是,操作系统需要一半(引用自己的代码和数据),为每个进程创建2GB的限制.如果您的32位应用程序尝试消耗超过其整个2GB的地址空间,它将返回"System.OutOfMemory",即使您的计算机的物理内存未满.
64位进程没有这个限制,因为它们使用64位指针,因此它们的理论最大地址空间为16艾字节(2 ^ 64).实际上,Windows x64将进程的虚拟内存限制为8TB.然后,内存限制问题的解决方案是以64位编译.
但是,默认情况下,Visual Studio中对象的大小仍限制为2GB.您将能够创建多个组合大小将大于2GB的阵列,但默认情况下不能创建大于2GB的阵列.希望如果您仍然想要创建大于2GB的数组,可以通过向app.config文件添加以下代码来实现: