.NET Framework 2.0 中的分析
分析 API 在 .NET Framework 2.0 版中得到了增强,可以提供额外的功能。 新功能是通过以下两个新接口公开的:ICorProfilerCallback2 和 ICorProfilerInfo2。
针对 .NET Framework 1.0 或 1.1 版编写的探查器 DLL 将无法在 .NET Framework 2.0 公共语言运行时 (CLR) 环境中正常运行。 若要更新探查器 DLL 以与 2.0 版或更高版本协同工作,您必须实现 ICorProfilerCallback2 接口。 ICorProfilerInfo2 接口继承自 ICorProfilerInfo 接口,并引入了一些新方法,这些方法支持与 CLR 进行增强的交互。
以下各部分对这些更改进行了探讨:
泛型
代码拆分
移除了进程内调试
本机映像生成器回调
增强的垃圾回收回调
冻结对象
其他 API 更改
除了 API 更改之外,添加了一个新的 HRESULT,即 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE。 有关可能返回此 HRESULT 的情况的信息,请参见 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。
泛型
运行时中泛型的引入使得分析 API 发生了三点变化:
typedef 标记和 ClassID 值之间或者 MethodDef 标记和 FunctionID 值之间不再存在一对一映射关系。 这是因为可能已为多种不同类型实例化了各个类或函数。 探查器作者应当阅读分析和运行时通知 ID,试验如何在自己的代码中使用 ICorProfilerInfo::GetClassFromToken 和 ICorProfilerInfo::GetFunctionFromToken 方法,并以能够识别泛型的方式重写代码。 分析 API 提供了两种新方法(ICorProfilerInfo2::GetClassFromTokenAndTypeArgs 和 ICorProfilerInfo2::GetFunctionFromTokenAndTypeArgs)来支持泛型。
FunctionID 与其包含的 ClassID 之间不再存在直接映射。 通过代码共享优化,不同的泛型类型实例化将能够共享代码。 只有在函数的特定激活上下文中进行检查时,您才能确定 FunctionID 的 ClassID。
ICorProfilerInfo 接口中的现有类和函数信息方法未提供有关泛型类型和函数的类型参数的信息。 为实现此目的,已提供了 ICorProfilerInfo2::GetClassIDInfo2 和 ICorProfilerInfo2::GetFunctionInfo2 方法。 请注意,这些方法并不能始终提供此信息;有关更多信息,请参见分析和运行时通知 ID。
返回页首
代码拆分
.NET Framework 中的程序集已经过性能优化。 预编译的本机代码已按函数拆分为多个区域。 因此,现有的 ICorProfilerInfo::GetCodeInfo 方法不再能够正确地描述函数的本机代码的范围。 探查器应切换到改用更常规的 ICorProfilerInfo2::GetCodeInfo2 方法。
返回页首
移除了进程内调试
在 .NET Framework 2.0 中,进程内调试被替换为一组与分析 API 一致的功能。 因此,就有了堆栈快照(请参见分析概述)和对象检查功能。
返回页首
本机映像生成器回调
本机映像生成器 (NGen.exe) 进行了重大优化,使得更多的工作从运行时转移到了生成本机映像时。 这使得分析 API 的行为发生了以下变化:
对于大多数函数,将不再在本机映像中接收 JITCachedFunctionSearch 回调。 探查器有两个取决于其回调使用方式的选项:
如果探查器使用回调来收集有关函数的信息,它可以切换到这样一种方案:在该方案中,只有在程序执行过程中第一次遇到某个给定函数时,才会收集有关该函数的信息。
如果探查器为检测目的而使用回调强制对函数进行实时 (JIT) 编译,则它可以改用增强型探查器本机映像。 有关更多信息,请参见分析 API 中的代码生成。
对于大多数类型,将不再在本机映像中接收 ClassLoad 回调。 对于这样的类,探查器应使用运行时求值技术(也称为“惰性求值”)。 已经在使用增强型探查器本机映像的探查器不必改变其行为。 但是,除非探查器出于其他原因需要增强型探查器本机映像,否则它不应切换到这些映像,因为增强型探查器本机映像与常规映像明显不同。
返回页首
增强的垃圾回收回调
垃圾回收回调在若干方面得到了增强。 回调现在将通知探查器垃圾回收句柄已创建或销毁,提供有关要终结的对象的队列的信息,并使用 Collect 方法来强制进行垃圾回收。 ICorProfilerCallback2::RootReferences2 方法(ICorProfilerCallback::RootReferences 的扩展)提供有关每个根的类型的信息。 最后,ICorProfilerCallback2::SurvivingReferences 方法可报告因非压缩垃圾回收而在堆中形成的对象布局。
返回页首
冻结对象
.NET Framework 2.0 中新的冻结对象是一些常量对象,这些对象在本机映像生成时初始化,并写入到本机映像中。 垃圾回收不会重新定位冻结对象,但垃圾回收对象可能会引用它们。 利用新的 ICorProfilerInfo2::EnumModuleFrozenObjects 方法,探查器能够枚举冻结对象。
返回页首
其他 API 更改
.NET Framework 2.0 还包含以下 API 更改:
ICorProfilerInfo::SetFunctionReJIT 方法现在返回 E_NOIMPL。 在早期版本中,调用此方法会导致死锁。
新的 ICorProfilerCallback2::ThreadNameChanged 方法提供线程名称更改的通知。
新的 ICorProfilerInfo2::GetThreadAppDomain 方法接受线程 ID,并返回线程在其中执行的应用程序域。
返回页首