CLR运行时细节
来源:互联网 发布:网络电视费用多少钱 编辑:程序博客网 时间:2024/05/17 09:07
关于多态不多解释了,在运行时决定和调用具体的实现,是面向对象的基础 设计模式的基础.
准备把继承多态和接口多态分开,因为从CLR实现的角度继承多态相比于接口多态要简单得多,也更容易理解,本篇只讨论继承多态, .NET Framework 2.0 和 4.0 这两个版本在实现上稍微有点区别(这里先忽略方法Jit编译的过程,只关注实现的方式).
废话不多,先看代码: C# Polymorphism01.cs
编译代码 先用 .Net Framework 2.0 编译:
运行 Polymorphism01_2.0.exe
启动windbg 附加进程 加载SOS
查找对应的模块:
!Name2EE *!Polymorphism01_2.0.exe
根据模块查找方法表:!DumpModule -mt 00af2c5c
先分别看下 BaseClass BrotherClass DerivedOfBrotherClass 这3个继承关系类的方法表(MethodTable)
可以看到第一个虚方法(ToString)的入口都是在方法表偏移28h的位置,其顺序是先父类,再子类,这样的安排让所有同一个家族(继承关系)的类型继承虚方法的顺序是一样的,并且偏移量是一样的,所有的类型(除了接口类型)的父类都是(或者间接是)System.Object,所以前4个虚方法肯定是Object里的4个虚方法(ToString Equals GetHashCode Finalize)
通过Program 的方法表(MethodTable)找到Main方法的入口地址:!DumpMT -md 00af302c
Main方法已经Jit编译,看看被编译成啥样子:!u 01010070
这里最重要的几行:
可以看到 继承多态在CLR运行时的实现是通过方法表的偏移 间接调用的,而方法表内继承虚方法的构建顺序是先父类再子类,由于.NET是单一继承,这样就确保了在同一家族的同一虚方法的偏移量是一样的.
接下来用Framework 4.0 编译下源码,4.0 和2.0相比 在实现上多了一层间接寻址,但思路是一样的
运行 Polymorphism01_4.0.exe
启动windbg 附加进程 加载SOS (这里要加载对于4.0的sos.dll)
直接查找Main方法:
!Name2EE Polymorphism01_4.0.exe Program.Main
看Main方法的区别:
!u 033a0070
这里只截取最重要的一段,调用构造器和其他的部分都先忽略.NET 4.0 比2.0 多了一次间接寻址,就是先偏移到虚表的入口,再从这个入口开始偏移到相应的方法,这样的好处(个人觉得)虚表的存储位置可以更灵活 如果方法表(MT)包含多个可变长结构也没问题 只要入口地址保存在偏移28h的位置即可
参考文档:
https://www.microsoft.com/china/MSDN/library/netFramework/netframework/JITCompiler.mspx?mfr=true
http://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti
http://blogs.microsoft.co.il/sasha/2012/03/15/virtual-method-dispatch-and-object-layout-changes-in-clr-40/
http://www.cnblogs.com/BlueTzar/articles/884694.html
相关文章:
CLR运行时细节 - Method Descriptor
原文地址:https://espider.github.io/CLR/inheritance-polymorphism/
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
- CLR运行时细节
- CLR运行时细节
- 公共语言运行时(CLR)
- CLR(公共语言运行时)
- CLR(公共语言运行时)
- 公共语言运行时 CLR
- CLR----公共语言运行时
- CLR----公共语言运行时
- CLR:在公共语言运行时
- CLR运行简述
- CLR运行原理
- CLR(公共语言运行时)到底藏在哪?
- 公共语言运行时CLR(第二课)
- 问题细节、Ajax、CLI、CLR、Dictionary
- 公共语言运行库CLR
- 公共语言运行库(CLR)
- C++手动加载CLR运行托管程序(CLR Hosting)
- 编写执行你的第一个Yukon CLR(通用语言运行时)存储过程
- 想和你一起为 Visual Studio 庆祝20岁生日
- web-前端之可移动的登录界面,并且可实现用户名重复的判断等表单事件
- 快速搭建本地 .NET Core 运行时调试环境
- 开源库 Natasha2016 ,让IL编程跑起来
- Rider IDE恢复了对.NET Core调试的支持
- CLR运行时细节
- Microsoft发布新工具,简化JavaScript Web应用的创建
- JavaScript设计模式之-----命令模式
- 数据库权限分配探讨
- CLR运行时细节
- .Net异步编程知多少
- 【南京】.Net 开源基础服务线下技术交流会
- 深入理解Async/Await
- Azure SQL的DTU和eDTU到底是个什么鬼