分析 API 中的对象检查
本主题讨论如何使用分析方法检查对象。
FunctionEnter2 和 FunctionLeave2 回调
FunctionEnter2 和 FunctionLeave2 回调提供有关参数的信息并以内存区域的形式返回函数值。 参数按从左到右的顺序存储在给定的内存区域中。 如下表所示,探查器可以使用函数的元数据签名来解释参数。
元素类型 |
表示形式 |
---|---|
基元(ELEMENT_TYPE <= R8、I、U) |
基元值。 |
值类型 (VALUETYPE) |
取决于类型。 |
引用类型(CLASS、STRING、OBJECT、ARRAY、GENERICINST、SZARRAY) |
ObjectID(指向垃圾回收堆的指针)。 |
BYREF |
托管指针(不是 ObjectID,但可能指向堆栈或垃圾回收堆)。 |
PTR |
非托管指针(不会因为垃圾回收操作而移动)。 |
FNPTR |
指针大小的不透明度值。 |
TYPEDBYREF |
托管指针,后跟指针大小的不透明度值。 |
ObjectID 与托管指针之间的区别如下所示:
ObjectID 只指向垃圾回收堆或冻结的对象堆。 托管指针也可以指向堆栈。
ObjectID 始终指向对象的开头部分。 托管指针可以指向对象的一个字段。
托管指针无法传递到需要 ObjectID 的函数。
有关可用的 CLR 类型的列表,请参见 CorElementType 枚举。
检查复杂类型
检查引用类型或非基元值类型涉及一些高级技巧。
对于不同于字符串或数组的值类型和引用类型,ICorProfilerInfo2::GetClassLayout 方法为每个字段提供了偏移量。 然后,探查器可以使用元数据来确定字段的类型并采用递归方式对其进行求值。
注意 |
---|
GetClassLayout 只返回类本身所定义的字段;父类所定义的字段不包括在内。您可以使用 ICorProfilerInfo2::GetClassIDInfo2 方法查找父类的 ClassID,然后使用 GetClassLayout 获取有关父类所定义的字段的信息。 |
对于已装箱的值类型,ICorProfilerInfo2::GetBoxClassLayout 方法将提供框中的值类型的偏移量。 值类型布局本身不会发生变化。 因此,探查器在框中一旦发现值类型,便可使用 GetClassLayout 了解其布局。
对于字符串,ICorProfilerInfo2::GetStringLayout 方法将提供字符串对象中所关注的数据块的偏移量。
数组有点特殊,因为您必须为每个数组对象(而不是每种数组类型)调用方法。 (这是因为数组格式太多而无法使用偏移量来进行描述。)所提供的 ICorProfilerInfo2::GetArrayObjectInfo 方法用于进行解释。
检查静态字段
有四种静态字段类型。 下表描述了这四种静态字段以及如何识别它们。
静态类型 |
定义 |
在元数据中的显示方式 |
---|---|---|
AppDomain |
基本静态字段。 它在每个应用程序域中都具有一个不同的值。 |
无附加自定义特性的静态字段。 |
Thread |
托管线程本地存储区 (TLS)。 这是一个对于每个线程和每个应用程序域都具有一个唯一值的静态字段。 |
用 ThreadStaticAttribute 标记的静态字段。 |
RVA |
在模块的数据节中具有 home 的进程范围内的静态字段。 |
具有 hasRVA 标志的静态字段。 |
上下文 |
在每个 COM+ 上下文中都具有不同值的静态字段。 |
用 ContextStaticAttribute 标记的静态字段。 |
ICorProfilerInfo2::GetThreadStaticAddress、ICorProfilerInfo2::GetAppDomainStaticAddress、ICorProfilerInfo2::GetContextStaticAddress 和 ICorProfilerInfo2::GetRVAStaticAddress 方法提供了有关静态字段位置的信息。 通过查看该位置处的内存,您对它的解释如下:
引用类型:ObjectID。
值类型:包含实际值的框的 ObjectID。
基元类型:基元值。
参考
ICorProfilerInfo2::GetClassLayout 方法
ICorProfilerInfo2::GetBoxClassLayout 方法
ICorProfilerInfo2::GetStringLayout 方法
ICorProfilerInfo2::GetArrayObjectInfo 方法
ICorProfilerInfo2::GetThreadStaticAddress 方法
ICorProfilerInfo2::GetAppDomainStaticAddress 方法
ICorProfilerInfo2::GetContextStaticAddress 方法
ICorProfilerInfo2::GetRVAStaticAddress 方法