高频堆

谁能解释一下CLR的“HighFrequencyHeap”?

高频堆用于存储常用的内部数据结构,例如类型的方法表。 这可以使用WinDbg / SOS进行validation,如下所示。

SSCLI书 (第235页)也对此进行了说明。

这是!eeheap输出的一部分

 -------------------------------------- Domain 1: 006428c0 LowFrequencyHeap: 00340000(2000:2000) Size: 0x2000 (8192) bytes. HighFrequencyHeap: 00342000(8000:2000) Size: 0x2000 (8192) bytes. StubHeap: Size: 0x0 (0) bytes. Virtual Call Stub Heap: IndcellHeap: Size: 0x0 (0) bytes. LookupHeap: Size: 0x0 (0) bytes. ResolveHeap: Size: 0x0 (0) bytes. DispatchHeap: Size: 0x0 (0) bytes. CacheEntryHeap: Size: 0x0 (0) bytes. Total size: Size: 0x4000 (16384) bytes. -------------------------------------- Jit code heap: LoaderCodeHeap: 004e0000(10000:1000) Size: 0x1000 (4096) bytes. Total size: Size: 0x1000 (4096) bytes. -------------------------------------- Module Thunk heaps: Module 5ef21000: Size: 0x0 (0) bytes. Module 00342e9c: Size: 0x0 (0) bytes. Total size: Size: 0x0 (0) bytes. -------------------------------------- Module Lookup Table heaps: Module 5ef21000: Size: 0x0 (0) bytes. Module 00342e9c: Size: 0x0 (0) bytes. Total size: Size: 0x0 (0) bytes. -------------------------------------- Total LoaderHeap size: Size: 0x13000 (77824) bytes. ======================================= Number of GC Heaps: 1 generation 0 starts at 0x02521018 generation 1 starts at 0x0252100c generation 2 starts at 0x02521000 ephemeral segment allocation context: none segment begin allocated size 02520000 02521000 0252e010 0xd010(53264) Large object heap starts at 0x03521000 segment begin allocated size 03520000 03521000 03523250 0x2250(8784) Total Size: Size: 0xf260 (62048) bytes. ------------------------------ GC Heap Size: Size: 0xf260 (62048) bytes. 

注意高频堆的位置和垃圾收集堆。 这是静态分配的Program实例的!dumpobject的输出。

 0:000> !dumpheap -type Program Address MT Size 0252b630 00343858 12 total 0 objects Statistics: MT Count TotalSize Class Name 00343858 1 12 TestBench2010.Program Total 1 objects 0:000> !do 0252b630 Name: TestBench2010.Program MethodTable: 00343858 EEClass: 0034154c Size: 12(0xc) bytes File: C:\workspaces\TestBench2010\TestBench2010\bin\Debug\TestBench2010.exe Fields: MT Field Offset Type VT Attr Value Name 00343858 4000001 4 ...Bench2010.Program 0 static 0252b630 p 0:000> !dumpheap -type Program Address MT Size 0252b630 00343858 12 total 0 objects Statistics: MT Count TotalSize Class Name 00343858 1 12 TestBench2010.Program Total 1 objects 0:000> !do 0252b630 Name: TestBench2010.Program MethodTable: 00343858 EEClass: 0034154c Size: 12(0xc) bytes File: C:\workspaces\TestBench2010\TestBench2010\bin\Debug\TestBench2010.exe Fields: MT Field Offset Type VT Attr Value Name 00343858 4000001 4 ...Bench2010.Program 0 static 0252b630 p 

请注意类型Program静态引用p的地址。 它指向垃圾收集堆中的地址。 另请注意方法表的地址。 它指向高频堆中的地址。

每个静态变量都存储在堆上,无论它是在引用类型还是值类型中声明。 无论创建多少个实例,总共只有一个插槽。 (不需要为该一个插槽创建任何实例。)请注意,此堆与正常的垃圾收集堆是分开的 – 它被称为“高频堆”,每个应用程序域都有一个。

从这里偷来了 。

在.Net运行时内部的这篇优秀的MSDN文章中,可以很好地概述各种“加载器堆”,其中高频堆就是一个例子。

从那篇文章:

经常访问的工件(如MethodTables,MethodDescs,FieldDescs和Interface Maps)将在HighFrequencyHeap上分配,而不常访问的数据结构(如EEClass和ClassLoader及其查找表)将在LowFrequencyHeap上分配。 StubHeap托管存根,便于代码访问安全性(CAS),COM包装调用和P / Invoke。

高频堆的要点是使经常访问的对象彼此靠近存储。 这最小化了该过程的工作集。