作为 .Net 攻城师,所必需掌握的 .Net Profiling 技术(作为恶役大小姐就该养魔王)

网友投稿 809 2022-08-29

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

作为 .Net 攻城师,所必需掌握的 .Net Profiling 技术(作为恶役大小姐就该养魔王)

.Net Profiling

在进行应用性能优化实践时,首先面对的就是热点定位,即确定那些带来巨大资源耗散的代码位置。而在不借助外部工具的前提下,定位资源热点是一件相当困难的事。它需要当事人对于应用实现本身有一个整体的把握,了解应用架构内每一个功能模块代码的路径与细节。与此同时,当事人还要对于应用实现所依赖的第三方功能库的表现有一定的把握。对于那些具备一定规模的应用系统,具备前述素质的工程师的数量屈指可数。而即便是这些百里挑一的优秀人才,其热点预估也不能保证一定是准确的。

Profiling API

需要补充说明一点,上文所说的 ICorProfilerCallback 接口实际上存在有 ICorProfilerCallback ~ ICorProfilerCallback7 这样7个版本的接口定义。高标号的接口版本向下兼容,但会提供新的功能扩展。不过,更高标号的接口往往也需要有更新版本的 CLR 来支持(如调用 ICorProfilerCallback7 需要在环境中部署 .Net Framework 4.6.1 以上版本),在实际使用时需要多加注意。

目前 Profiling API 所支持的特性

正如前文所述,Profiler 对于程序行为的描述源自 profiling API 所提供的信息。在目前版本中,凭借 profiling API 能够获取到下列事件的消息通知:

随着 .Net 技术的演进,未来的 Profiling API 或许能够提供更多的信息。不过,以下功能点是 Profiling API 不会实现的,请在应用时回避:

非托管代码的执行信息 运行时修改自身代码的应用的 Profiling(如 AOP) 边界检验 远程 profiling 高可靠性环境下的 profiling

线程相关

对于加载了 Profiler DLL 的进程而言,其在创建新线程时,新线程本身也会产生 ICorProfilerCallback 接口下定义的各种事件通知。这一过程中,Profiler 不必去显式地指定一个 ThreadID 以使得 Profiling API 生效。同样的,Profiler 完全可以简单地在代码中使用 thread-local 的存储方式,用不着费心地去进行存储位置的全局重定向。

还有一个线程相关的问题是来自于 COM 接口的。上文中我们说过 Profiler 事实上是实现为一个 COM 组件的,但其实 CLR 在运行时并不会去初始化 COM。这是为了避免在应用代码指定线程模型前,CLR 调用 [CoInitialize][Ref12] 来指定应用线程模型。同样地,在 Profiler 内部,不要去调用 CoInitialize 以避免与应用代码产生冲突。

调用栈

获取调用栈信息是应用 Profiling 时的一项关键需求。针对这一需求,Profiling API 提供给 Profiler 编写者两种实现方式:栈快照和倒影栈。

其他需要留意之处

前文强调过,Profiler 是一个非托管的 DLL 库,会在应用运行时被加载到 CLR 中并与应用处于同一进程空间下。如此,Profiler DLL 实质上是不受托管代码的访问控制的。其运行唯一的限制就是运行 Profiler 的 OS 用户必须拥有足够权限。因此,对于要部署 Profiler 的技术人员来说,必须要明白这其中可能的风险,提早进行准备。例如可以把 Profiler DLL 加到访问控制列表(ACL)中以免恶意用户对其加以利用。

还有,Profiler DLL 作为 CLR 的一个插件,其运行错误可能会引起 CLR 本身的崩溃,在实施时一定要足够小心。而对于那些运行在栈内存空间紧张的环境下的 Profiler,要警惕因为 ICorProfilerCallback 导致栈溢出而引起的应用崩溃。在这种资源受限的环境中,要尽可能地减少 Profiler 自身的资源耗散。尽力避免原本能够运行的应用因为 Profiler 而导致无法运行的情况。

结语

本文简述了 .Net Profiling 技术的总体情况,并就其中的一些重要技术点进行了阐述。希望能帮助读者初步理解 .Net Profiling 技术。后续,我们将具体到代码实施层面,就 .Net Profiling 的实现进行详细讨论

上一篇:深入浅出 ES6:ES6 与 Babel / Broccoli 的联用(深入浅出下一句是啥)
下一篇:真事儿!——我们官网被全站拷贝了!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~