关于集合中可以包含的最大项目数的主要问题,例如List.我在这里寻找答案,但我不理解这个推理.
假设我们正在与一个List<int>具有sizeof(int)= 4个字节......每个人都似乎是确保为64,你可以有一个最大268435456 int和x86的最大134217728 int.链接:
但是,当我自己测试时,我发现x86并非如此.谁能指出我可能出错的地方?
//// Test engine set to `x86` for `default processor architecture`
[TestMethod]
public void TestMemory()
{
var x = new List<int>();
try
{
for (long y = 0; y < long.MaxValue; y++)
x.Add(0);
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Actual capacity (int): " + x.Count);
System.Diagnostics.Debug.WriteLine("Size of objects: " + System.Runtime.InteropServices.Marshal.SizeOf(x.First().GetType())); //// This gives us "4"
}
}
Run Code Online (Sandbox Code Playgroud)
对于x64:268435456(预期)
对于x86:67108864(比预期少2倍)
为什么人们说包含134217728的List int正好是512MB内存...当你有134217728*sizeof(int)*8 = 4,294,967,296 = 4GB时......每个进程的限制超过2GB.而67108864*sizeof(int)*8 = 2,147,483,648 = 2GB ......这是有道理的.
我在运行Windows 7 8GB RAM的64位机器上使用.NET 4.5.在x64和x86中运行我的测试.
编辑:当我直接设置容量List<int>(134217728)我得到一个System.OutOfMemoryException.
EDIT2:我的计算错误:乘以8是错误的,实际上MB =/= Mbits.我在计算Mbits.仍然67108864英寸只有256MB ...这比预期的要小.
类的底层存储List<T>是一个T[]数组.对数组的一个硬性要求是进程必须能够分配连续的内存块来存储数组.
这是32位进程中的一个问题.虚拟内存用于代码和数据,您可以从它们之间留下的漏洞进行分配.虽然一个32位进程将拥有2 GB的内存,但你永远不会到达接近该大小的一个洞.在您启动程序后,您可以获得的地址空间中最大的漏洞大约为500或600兆字节.给予或接受,这很大程度上取决于加载到进程中的DLL.不仅仅是CLR,框架程序集的抖动和本机映像,还有与托管代码无关的那种.就像反恶意软件和大量"有用"实用程序一样,它们会自动进入Dropbox和shell扩展等每个进程.一个基础不善的人可以在两个小洞中切出一个漂亮的大洞.
随着程序分配和释放内存一段时间,这些漏洞也会变小.一个称为地址空间碎片的一般问题.即使存在大量未使用的内存,长时间运行的进程也可能在90 MB分配上失败.
您可以使用SysInternals的VMMap实用程序来获得更多信息.Russinovich的书籍Windows Internals的副本通常也是必要的,以便了解您所看到的内容.
| 归档时间: |
|
| 查看次数: |
749 次 |
| 最近记录: |