有大量有关 .NET LOH 的信息,并且已在各种文章中进行了解释。不过,有些文章似乎缺乏一点精确性。
过时的信息
In Brian Rasmussen 的回答 (2009),Microsoft 项目经理 https://stackoverflow.com/a/687155/480982,他说限制是 85000 字节。他还让我们知道还有一个更奇怪的案例double[]
大小为 1000 个元素。同样的 85000 限制由Maoni Stephens(MSDN,2008),CLR 团队成员 https://msdn.microsoft.com/en-us/magazine/cc534993.aspx.
在评论中,Brian Rasmussen 变得更加准确,让我们知道它可以用byte[]
85000 字节 - 12 字节。
2013年更新
Mario Hewardt(《高级 Windows 调试》作者) http://blogs.msdn.com/b/mariohewardt/archive/2013/06/26/no-more-memory-fragmentation-on-the-large-object-heap.aspx2013 年告诉我们,.NET 4.5.1 现在也可以压缩 LOH,如果我们告诉它这样做的话。由于默认情况下它是关闭的,因此问题仍然存在,除非您已经意识到这一点。
2015年更新
我无法重现byte[]
再举个例子吧。通过一个简短的强力算法,我发现我必须减去 24 (byte[84999-24]
在苏俄,byte[85000-24]
在洛):
static void Main(string[] args)
{
int diff = 0;
int generation = 3;
while (generation > 0)
{
diff++;
byte[] large = new byte[85000-diff];
generation = GC.GetGeneration(large);
}
Console.WriteLine(diff);
}
我也无法重现double[]
陈述。暴力破解给了我 10622 个元素作为边界(double[10621]
在苏俄,double[10622]
在洛):
static void Main(string[] args)
{
int size = 85000;
int step = 85000/2;
while (step>0)
{
double[] d = new double[size];
int generation = GC.GetGeneration(d);
size += (generation>0)?-step:step;
step /= 2;
}
Console.WriteLine(size);
}
即使我为较旧的 .NET 框架编译应用程序,也会发生这种情况。它也不依赖于发布或调试版本。
如何解释这些变化?