高频堆

16

有人能解释一下CLR的"HighFrequencyHeap"吗?

4个回答

12
高频堆用于存储常用的内部数据结构,例如类型的方法表。可以使用WinDbg/SOS验证,如下所示。 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的地址。它指向垃圾回收堆中的一个地址。另外,请注意方法表的地址。它指向高频堆中的一个地址。


2
每个静态变量都存储在堆上,无论它是在引用类型还是值类型中声明的。无论创建多少实例,总共只有一个槽位。 (虽然不需要创建任何实例该槽位也存在)。请注意,此堆与普通垃圾回收堆分开 - 它称为“高频率堆”,每个应用程序域都有一个。摘自此处

你的意思是垃圾回收器不会处理静态变量?那它怎么能从内存中释放呢? - Vikram
那么静态类和静态变量或方法之间有什么区别呢? - Vikram
2
静态变量的整个意义在于它们存在于应用程序域的生命周期中,因此根据定义,它们永远不会被垃圾回收 - 至少在应用程序域/进程退出之前不会。至于静态类、静态方法和静态变量之间的区别,它们完全不同,这是C# 101的区别。静态变量是“类级别”的 - 在整个应用程序域中创建一个变量实例,并根据其所在的类进行作用域限定。静态方法是类中不需要在实例上调用的方法 - 它们基本上是全局函数。 - Chris Tavares
1
静态类是只包含静态方法的类,编译器不允许您添加常规方法或构造函数或从中派生。静态类实际上只是一种命名空间机制,用于放置全局函数。 - Chris Tavares

2
在这篇关于 .Net 运行时内部的优秀 MSDN 文章中,有一个很好的 "加载器堆" 概述,其中高频堆就是一个例子。
根据该文章:
经常访问的工件(如 MethodTables、MethodDescs、FieldDescs 和 Interface Maps)会在 HighFrequencyHeap 上分配,而不经常访问的数据结构(如 EEClass 和 ClassLoader 及其查找表)则会在 LowFrequencyHeap 上分配。StubHeap 托管用于支持代码访问安全性(CAS)、COM 包装器调用和 P/Invoke 的存根。

额,为什么微软不能像应该对待永久资源一样对待文章网址。他们会学习吗?感谢互联网档案馆的修复。请考虑捐赠!www.archive.org - codekaizen
1
或者也许是这个(警告:.chm文件):http://download.microsoft.com/download/3/a/7/3a7fa450-1f33-41f7-9e6d-3aa95b5a6aea/MSDNMagazineMay2005en-us.chm - Vlad
1
@codekaizen:不幸的是,WebArchive目前在俄罗斯被禁止访问。 - Nick Volynkin

-2
高频堆的目的是将经常访问的对象存储在彼此靠近的位置,从而最小化进程的工作集。

从CLR的角度来看,这听起来并不正确。 - codekaizen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接