为什么大对象堆和何必计较?对象

2023-09-02 21:10:09 作者:染火枫林

我看了一下世代和大对象堆。但我还是不明白有大对象堆有何意义(或利益)?

I have read about Generations and Large object heap. But I still fail to understand what is the significance (or benefit) of having Large object heap?

什么可能出了问题(在性能和内存方面)如果CLR会不过是仗着第2代(考虑到门槛Gen0和第一代小,以处理大对象)来存储大对象?

What could have went wrong (in terms of performance or memory) if CLR would have just relied on Generation 2 (Considering that threshold for Gen0 and Gen1 is small to handle Large objects) for storing large objects?

推荐答案

一个没有垃圾收集刚刚摆脱未被引用的对象,它也的契约的堆。这是一个非常重要的优化。它不只是让内存的使用更有效率的(未使用的孔),它使CPU高速缓存更有效。缓存是现代处理器的真正的大交易,他们是一个数量级的易秩序比内存总线速度更快。

A garbage collection doesn't just get rid of unreferenced objects, it also compacts the heap. That's a very important optimization. It doesn't just make memory usage more efficient (no unused holes), it makes the CPU cache much more efficient. The cache is a really big deal on modern processors, they are an easy order of magnitude faster than the memory bus.

压实由复制字节简单地完成。然而,这需要时间。对象越大,越​​有可能复制它超过了可能的CPU高速缓存使用的改进的成本。

Compacting is done simply by copying bytes. That however takes time. The larger the object, the more likely that the cost of copying it outweighs the possible CPU cache usage improvements.

于是他们跑了一堆基准,确定盈亏平衡点。而到了85000个字节为分界点拷贝不再提高PERF。随着双阵列的一个特殊的例外,它们被认为是大时,阵列有超过1000个元素。这是另一个优化32位code,大对象堆分配器具有特殊的属性,在这一点上都符合8个地址分配内存,不像正规代分配的只分配对准4.调整是一个大应对双,读取或写入失去定位双是非常昂贵的。奇怪的是稀疏微软信息从来不提长,不知道数组怎么了这一点。

So they ran a bunch of benchmarks to determine the break-even point. And arrived at 85,000 bytes as the cutoff point where copying no longer improves perf. With a special exception for arrays of double, they are considered 'large' when the array has more than 1000 elements. That's another optimization for 32-bit code, the large object heap allocator has the special property that it allocates memory at addresses that are aligned to 8, unlike the regular generational allocator that only allocates aligned to 4. That alignment is a big deal for double, reading or writing a mis-aligned double is very expensive. Oddly the sparse Microsoft info never mention arrays of long, not sure what's up with that.

FWIW,还有很多关于没有得到压缩大对象堆程序员焦虑。这时候,他们写的就是超过一半的整个可用地址空间的程序总是被触发。其次是使用工具像一个内存分析器找出为什么程序轰炸,尽管仍有大量未使用的虚拟内存。这种工具显示了孔蕙,内存未使用的块,其中previously一个大对象住,但得到了垃圾回收。这样是蕙的必然价格,孔只能重复使用由分配的对象是相同或小型化。真正的问题是假设方案应允许消耗的所有的虚拟内存在任何时候。

Fwiw, there's lots of programmer angst about the large object heap not getting compacted. This invariably gets triggered when they write programs that consume more than half of the entire available address space. Followed by using a tool like a memory profiler to find out why the program bombed even though there was still lots of unused virtual memory available. Such a tool shows the holes in the LOH, unused chunks of memory where previously a large object lived but got garbage collected. Such is the inevitable price of the LOH, the hole can only be re-used by an allocation for an object that's equal or smaller in size. The real problem is assuming that a program should be allowed to consume all virtual memory at any time.

否则,只需运行在64位操作系统的code完全消失的一个问题。 64位进程的虚拟内存地址空间中的 8兆兆字节可用,幅度超过32位进程的3个数量级。孔你不能跑出去。

A problem that otherwise disappears completely by just running the code on a 64-bit operating system. A 64-bit process has 8 terabytes of virtual memory address space available, 3 orders of magnitude more than a 32-bit process. You just can't run out of holes.

长话短说,蕙使得code运行更加高效。在利用现有的虚拟内存地址空间的成本效率较低。

Long story short, the LOH makes code run more efficient. At the cost of using available virtual memory address space less efficient.

更新,.NET 4.5.1现在支持压缩蕙,GCSettings.LargeObjectHeapCompactionMode属性。当心后果吧。

UPDATE, .NET 4.5.1 now supports compacting the LOH, GCSettings.LargeObjectHeapCompactionMode property. Beware the consequences please.

 
精彩推荐
图片推荐