- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
有很多关于 .NET LOH 的可用信息,并且已经在各种文章中进行了解释。但是,似乎有些文章不够精确。
在Brian Rasmussen's answer (2009), program manager at Microsoft ,他说限制是 85000 字节。他还让我们知道有一个更奇怪的 double[]
案例,其大小为 1000 个元素。 Maoni Stephens (MSDN, 2008), member of the CLR team 规定了相同的 85000 限制.
在评论中,Brian Rasmussen 变得更加准确,让我们知道它可以用 85000 字节 - 12 字节的 byte[]
重现。
Mario Hewardt (author of 'Advanced Windows Debugging') 在 2013 年告诉我们,如果我们告诉它这样做,.NET 4.5.1 现在也可以压缩 LOH。由于它在默认情况下处于关闭状态,因此问题仍然存在,除非您已经意识到它。
我不能再重现 byte[]
示例了。使用简短的强力算法,我发现我必须减去 24(SOH 中的 byte[84999-24]
,LOH 中的 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 个元素作为边界(SOH 中的 double[10621]
,LOH 中的 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 框架编译应用程序,也会发生这种情况。它也不依赖于 Release 或 Debug 版本。
如何解释变化?
最佳答案
byte[]
示例中从 12 位到 24 位的变化可以用 CPU 架构从 32 位到 64 位的变化来解释。在为 x64 或 AnyCPU 编译的程序中,.NET 开销从 2*4 字节(4 字节对象头 + 4 字节方法表)增加到 2*8 字节(8 字节对象头 + 8 字节方法表)。此外,数组的长度属性为 4 字节(32 位)而不是 8 字节(64 位)。
对于double[]
的例子,用一个计算器就可以了:85000 bytes/64 bit for the double type = 10625 items,这已经很接近了。考虑到 .NET 开销,结果是(85000 字节 - 24 字节)/每个 double 8 个字节 = 10622 double 。因此,不再对 double[]
进行特殊处理。
顺便说一句,我以前从来没有找到任何关于 LOH 分片的工作演示,所以我自己写了一个。只需为 x86 编译以下代码并运行它。它甚至包括一些调试提示。
编译为 x64 时效果不佳,因为 Windows 可能会增加页面文件的大小,因此后续分配 20 MB 内存可能会再次成功。
class Program
{
static IList<byte[]> small = new List<byte[]>();
static IList<byte[]> big = new List<byte[]>();
static void Main()
{
int totalMB = 0;
try
{
Console.WriteLine("Allocating memory...");
while (true)
{
big.Add(new byte[10*1024*1024]);
small.Add(new byte[85000-3*IntPtr.Size]);
totalMB += 10;
Console.WriteLine("{0} MB allocated", totalMB);
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Memory is full now. Attach and debug if you like. Press Enter when done.");
Console.WriteLine("For WinDbg, try `!address -summary` and `!dumpheap -stat`.");
Console.ReadLine();
big.Clear();
GC.Collect();
Console.WriteLine("Lots of memory has been freed. Check again with the same commands.");
Console.ReadLine();
try
{
big.Add(new byte[20*1024*1024]);
}
catch(OutOfMemoryException)
{
Console.WriteLine("It was not possible to allocate 20 MB although {0} MB are free.", totalMB);
Console.ReadLine();
}
}
}
}
关于c# - LOH 碎片 - 2015 年更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30361184/
具有大量项目的.NET集合是否易于存储在LOH中? 我对列表和字典特别好奇。在我的代码中,我将大量(40k +)相对较小的对象(比如说1k)存储在临时列表和字典中以进行处理。这些收藏中的物品数量是否会
我有几百个 的实例我的类 存在于托管堆中。其中一些位于大对象堆中。下面是各种堆结构的样子 0:000> !EEHeap -gc Number of GC Heaps: 1 generation 0 s
在我的应用程序中,我需要将大文件(大约 250 MB)加载到内存中,我以一种惰性的方式进行——当用户要求查看文件时——我正在加载它。之后,每次用户尝试访问该文件时,我都能立即显示它,因为它已经位于内存
我们在 Server 2012 上有一个使用 WebApi 2、.NET 4.5 的 Web 服务。我们发现延迟偶尔会无缘无故地增加 10-30 毫秒。我们能够将有问题的代码片段追踪到 LOH 和 G
在与一位同事谈论一组特定的应用程序在启动时使用近 1.5G 内存时...他向我指出了一个很好的链接 .NET production debugging 让我困惑的部分是...... For examp
看了一些关于.Net/C#/CLR等的帖子和书籍,在微软2005年的presentation中找到了如下幻灯片: GC takes time – “% time in GC” counter If o
有很多关于 .NET LOH 的可用信息,并且已经在各种文章中进行了解释。但是,似乎有些文章不够精确。 过时信息 在Brian Rasmussen's answer (2009), program m
我正在使用下面的代码将大文件上传到服务器,并注意到将 FileStream 复制到 GetRequestStream 会创建字节数组并将其保存在内存中。这增加了大对象堆,我不想要它。也许有人知道如何解
我还有一个 Unresolved 问题 HERE关于一些可能涉及 LOH 碎片以及其他未知数的绝望内存问题。 我现在的问题是,公认的做事方式是什么?如果我的应用程序需要在 Visual C# 中完成,
我有一个类负责在下载管理器中下载文件。该类负责下载文件并将其写入给定路径。 要下载的文件大小通常在 1 到 5 MB 之间,但也可能更大。我正在使用 WebClient 类的实例从 Internet
我读到,在托管堆中固定对象会影响 .NET 中的 GC 性能,因为如果“妨碍”固定对象,GC 就无法压缩内存。但由于大型对象堆无论如何都不会被压缩,因此这不适用于 LOH 中的对象。固定 LOH 中的
我有一个 OData 响应作为 JSON (只有几 MB) 并且要求流式传输“JSON 的某些部分”,甚至不将它们加载到内存中。 例如:当我读取以下 JSON 中的属性“value[0].Body.C
已开发的新应用程序大量使用 Web 服务。我们开始定期遇到内存不足异常(随着使用量的增加)。在查看内存转储时,我注意到有大量相同大小的 byte[]。查看这些 byte[] 的句柄,我注意到它们被 S
好吧,这是我第一次尝试对 .NET 应用程序进行内存分析(我已经完成了 CPU 调整),但我在这里遇到了一些困难。 我的应用程序中有一个 View ,每页加载 40 张图片(最多),每张图片约 3MB
我是一名优秀的程序员,十分优秀!