![]() |
1
230
垃圾回收不仅可以清除未引用的对象,还可以 压实机 堆。这是一个非常重要的优化。它不仅使内存使用更高效(没有未使用的漏洞),还使CPU缓存更高效。缓存在现代处理器上非常重要,它们比内存总线快一个数量级。 压缩只需复制字节即可完成。然而,这需要时间。对象越大,复制它的成本就越有可能超过CPU缓存使用率的可能改善。 因此,他们运行了一系列基准测试来确定盈亏平衡点。达到85000字节作为复制不再提高性能的临界点。除了double数组的特殊例外,当数组包含1000多个元素时,它们被认为是“大”的。这是32位代码的另一个优化,大对象堆分配器具有特殊属性,它在与8对齐的地址处分配内存,这与只分配与4对齐的常规分代分配器不同。这种对齐对于double来说是一件大事,读取或写入对齐错误的double非常昂贵。奇怪的是,稀疏的微软信息从未提到长数组,不知道这是怎么回事。 Fw,有很多程序员担心大型对象堆没有被压缩。当他们编写的程序消耗了整个可用地址空间的一半以上时,这总是会被触发。随后,使用内存分析器等工具找出程序崩溃的原因,即使还有大量未使用的虚拟内存可用。这样的工具显示了LOH中的漏洞,即以前有一个大型对象存在但被垃圾收集的未使用的内存块。这就是LOH的不可避免的代价,这个洞只能通过为大小相等或更小的物体分配来重新使用。真正的问题是假设一个程序应该被允许消费 全部的 虚拟内存随时可用。 只需在64位操作系统上运行代码,这个问题就会完全消失。64位进程具有 8TB 虚拟内存地址空间比32位进程多3个数量级。你就是跑不出洞。 长话短说,LOH使代码运行更高效。以使用可用虚拟内存地址空间效率较低为代价。 更新。NET 4.5.1现在支持压缩LOH, GCSettings.LargeObjectHeapCompactionMode 财产。请小心后果。 |
![]() |
2
16
小对象堆(SOH)和大对象堆(LOH)的本质区别在于,SOH中的内存在收集时会被压缩,而LOH则不会,因为 this article 说明。压缩大型物体的成本很高。与本文中的示例类似,假设在内存中移动一个字节需要2个周期,那么在2GHz计算机中压缩8MB对象需要8ms,这是一个很大的成本。考虑到大型对象(在大多数情况下是数组)在实践中非常常见,我想这就是微软将大型对象固定在内存中并提出LOH的原因。 顺便说一句,根据 this post ,LOH通常不会产生内存碎片问题。 |
![]() |
3
11
如果对象的大小大于某个固定值(.NET 1中为85000字节),则CLR会将其放入大对象堆中。这优化了:
|
![]() |
4
5
其原理是,一个进程不太可能(也很可能是糟糕的设计)创建大量生命周期较短的大型对象,因此CLR将大型对象分配给一个单独的堆,并在其上以与常规堆不同的计划运行GC。 http://msdn.microsoft.com/en-us/magazine/cc534993.aspx |
![]() |
5
0
我不是CLR方面的专家,但我认为为大型对象设置一个专用堆可以防止对现有世代堆进行不必要的GC扫描。分配大型对象需要大量 连续 免费内存。为了从世代堆中分散的“洞”中提供这一点,你需要频繁的压缩(这只在GC循环中完成)。 |
![]() |
A B · C#Excel自动调整列避免长文本时出错 4 月前 |
![]() |
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 4 月前 |
![]() |
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 4 月前 |
|
Sei · Avalonia/WPF将路由器传递到控制模板 5 月前 |