ksm*_*ksm 12 .net c# out-of-memory
为什么这样:
class OutOfMemoryTest02
{
static void Main()
{
string value = new string('a', int.MaxValue);
}
}
Run Code Online (Sandbox Code Playgroud)
抛出异常; 但这不会:
class OutOfMemoryTest
{
private static void Main()
{
Int64 i = 0;
ArrayList l = new ArrayList();
while (true)
{
l.Add(new String('c', 1024));
i++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
有什么不同?
Ste*_*end 10
你有没有看过int.MaxValue文档?它相当于2GB,这可能比你用于连续的"a"字符块的RAM要多 - 这就是你在这里要求的.
http://msdn.microsoft.com/en-us/library/system.int32.maxvalue.aspx
你的无限循环最终会导致相同的异常(或者与过度使用RAM间接相关的另一个异常),但这需要一段时间.尝试增加1024以10 * 1024 * 1024在循环情况下更快地重现症状.
当我使用这个更大的字符串大小运行时,我在68次循环(检查i)后的10秒内得到异常.
您的
new string('a', int.MaxValue);
Run Code Online (Sandbox Code Playgroud)
抛出一个OutOfMemoryException简单因为.NET string有长度限制.MSDN文档中的"备注"部分说:
内存中String对象的最大大小为2 GB,即大约10亿个字符.
在我的系统(.NET 4.5 x64)new string('a', int.MaxValue/2 - 31)抛出,而new string('a', int.MaxValue/2 - 32)工作.
在第二个示例中,无限循环分配~2048个字节块,直到您的操作系统无法在虚拟地址空间中再分配任何块.当达到这个目标时,你也会得到一个OutOfMemoryException.
(~2048字节= 1024个字符*每个UTF-16代码点2个字节+字符串开销字节)
因为int.MaxValue是2,147,483,647,或者需要连续分配的2千兆字节.
在第二个示例中,OS每次只需要找到1024个字节进行分配,并且可以交换到硬盘驱动器.我相信如果你让它运行得足够长,你最终会在一个黑暗的地方:)