文档章节

C#类型、对象、线程栈、托管堆在CLR中的关系

蓝宇
 蓝宇
发布于 2017/04/09 14:54
字数 1363
阅读 108
收藏 0
点赞 0
评论 0

假设一个已经加载CLR组件的一个windows进程。该进程可能有多个线程。线程创建时会开辟栈空间。栈用于向方法传递实参,方法内部定义的局部变量也在栈上。

下图展示了线程的栈内存。栈从高位内存地址到地位内存地址构建。图中线程已经执行了一些代码,栈顶已经有些数据了,现在假设执行的代码调用了F1方法。

 

1. 首先它在线程栈上分配局部变量name的内存.

2. 然后F1调用F2方法,将局部变量name作为实参传递。name的局部变量地址被压入栈。

3. 调用方法有时会将返回地址压入栈

4. 在线程栈位length和tally分配内存。

5. 最终,F2抵达return,造成CPU指令指针被设置成栈的返回地址。F2的栈帧展开----出栈,栈的状态恢复到1的情况。

6. 最终F1会返回它的调用者。它的返回地址应该在1的上面。

 

现在讨论下一个话题

 

假定有以下两个类的定义:

internal class Employee{

     public Int32 GetYearsEmployed()  {...}

     public virtual String GetProgressReport() {...}

     public static Employee Lookup(String name){...}

}

internal sealed class Manager : Employee{

      public override String GetProgressReport(){...}        

}

 

注意:堆上所有对象都包含两个额外的成员:类型对象指针和同步块索引。

其中对象指针指向类别.

同步块当使用lock锁定对象时,对象的同步块被设置一个整数,这个整数就是同步块的数组索引。初始情况,同步块索引位负数,当lock结束时,同步块索引又重新被设置成负数。

上图线程已经执行了一些代码,马上就要调用F3方法。

1. 首先JT编译器将F3的IL代码换成CPU指令时,会注意到F3内部引用的所有类型是否全部加载,然后利用程序集的元数据,提取预支相关的信息,创建一些数据结构来表示类型本身。

2. 由于线程已经执行了一些代码。所以不妨认为Int32 和String类对象已经创建好了。

3. 由于Employee定义了三个方法,Manager只定义了一个方法,所以Manager的方法表中只有一个记录项。

4. 当CLR确定方法需要所有的类型对象都已经创建,F3的代码编译后就允许线程执行F3的代码,在代码执行时就会对线程栈中的局部变量进行内存分配,CLR会将局部变量初始为null或0.

5. F3构造一个Manager对象引用

6. 局部变量year

7. 执行new Mnager。在托管堆上创建Mnager类型的一个实例,也就是一个Manager对象,和所有对象一样Mnager对象也有类型对象指针和同步块索引,该对象还要包含必要的字节来容纳Manager类型定义的所有实例数据字段,以及任何基类的所有实例字段,任何时候在堆上新建对象,CLR都会自定初始化内部的类型对象指针来因用对象对应的类型对象。此外在调用类型的构造函数之前,CLR会初始化同步块索引,并将对象所有实例字段设为null或0.new 操作符返回Manager对象的内存地址,将地址保存到局部变量e中。

8. 下一行代码调用Employee的LookUp方法,在调用静态方法时,CLR会定位与定义静态方法的类型对应的类型对象,然后,JIT会在类型对象的方法表中查找与被调用方法对应的记录项,进行JIT编译(如果需要),然后调用编译好的代码,在调用此方法时,会在堆中构造一个新的Manager,e不再引用第一个Manager对象。

9. 下一行调用Employee的非虚实例方法GetYearsEmployee。调用非虚方法时,JIT会找到发出调用的哪个变量e的类型,这时e被定义成Employee,如果Employee没有此方法,JIT会一直回溯直到Object或找到那个方法。,之所以可以如此回溯,是因为每个类型对象都有一个字段引用了它的基类型。

10. F3的下一行调用Employee的虚方法GetProgressReport。调用虚实例方法时,JIT要在方法中生成一些额外的代码。方法每次调用都会执行这些代码,这些代码首先检查发出调用的变量,并跟随地址检查类型对象指针成员,该成员指向对象的实际类型,然后在实际类型的方法表中找到记录项。

 

注意:Employee和Manger类型对象都包含类型对象指针。这是因为类型对象本质上也是对象。CLR创建类型时,必须先初始化这些变量。CLR在运行时,会理解为MSCorLib.dll 中定义的System.Type类型创建一个特殊的类型对象。上述两个类型对象都是它的实例。所以它们的类型对象指针是System.Type类型对象的引用,而System.Type类型对象的类型对象指针是它自己。

 

© 著作权归作者所有

共有 人打赏支持
蓝宇
粉丝 1
博文 7
码字总数 5793
作品 0
呼和浩特
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?

什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从类型系统开始讲起,我将通过跨语言操作这个例子来逐渐引入一系列.NET的相关概念,这主要包括:...

dotNET跨平台
07/03
0
0
Perfmon.exe辅助检查.NET程序内存泄漏

因为工作用C#写的程序老是内存泄漏,在网上找了找资料后,发现了Windows自带的性能监视器Perfmon.exe可以辅助查看.NET程序的运行状况。今天研究了一番,下面的内容就是一些我认为比较重要需要...

北风其凉
2014/07/30
0
0
.net 中的托管与非托管

参考文献 关于托管与非托管 到底什么是托管,什么是非托管的研究 前言 最近在看《ASP.NET MVC 4框架揭秘》,里面有很多微软.net的东西,其中就很多次提到了托管与非托管,搞得我云里雾里的,...

嗯哼9925
2017/12/13
0
0
【译】.Net 垃圾回收机制原理(一)

有了Microsoft.Net clr中的垃圾回收机制程序员不需要再关注什么时候释放内存,释放内存这件事儿完全由GC做了,对程序员来说是透明的。尽管如此,作为一个.Net程序员很有必要理解垃圾回收是如...

长平狐
2012/06/08
53
0
C# vs C++之二:GC vs RAII

C# vs C++之二:GC vs RAII 资源管理 C中资源管理极为繁琐易错,大多复杂C系统都面临内存泄露、悬挂指针等问题 一方面由底层语言特点决定;另一方面也由于C语言特性相对较少,严重依赖程序员...

ddatsh
2011/06/28
897
6
[收藏]网上搜集的一系列C#面试题(持续更新……)

1.请你说说.NET中类和结构的区别? 答:结构和类具有大体的语法,但是结构受到的限制比类要多。结构不能申明有默认的构造函 数,为结构的副本是又编译器创建和销毁的,所以不需要默 认的构造函...

zting科技
2017/01/11
0
0
装箱(boxing)和拆箱(unboxing) [转]

装箱和拆箱 装箱 就是把“值类型”转换成“引用类型”; 拆箱 就是把“引用类型”转换成“值类型”; 首先,我们要弄明白为什么需要装箱和拆箱。C#的所有类型,包括int、boo等,都继承自Sys...

_编程菜鸟_
2015/08/21
0
0
.NET基础面试题整理

今年毕业,本学期找工作期间在面试前做的一些临时的准备 以下的关于老赵分享的面试题解答参考了手头的书籍和视频教程,以及网上的资料,现整理出来希望对大家有所帮助,不对或欠佳的地方望大...

mszhangxuefei
2011/04/16
0
0
C#性能理解以及CTS

关于C#/.NET性能 在上次的例子里面,第二次执行Console.WriteLine()方法时,会完全跳过JITCompiler编译。因为第一次已经完全编译为了本地CPU指令并且返回了指令在内容里的入口地址,所以这一...

mszhangxuefei
2012/07/10
0
0
从C++到C++/CLI

  刘未鹏(pongba) /文   看起来只是在C++后面多写了一个“/CLI”,然而其意义却远不止于此,google的c++.moderated版上为此还发起了数星期的讨论,在国内大部分人对C++/CLI还不是很了解的...

文艺小青年
2017/06/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
3分钟前
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
10分钟前
0
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
15分钟前
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0
iptables规则备份和恢复、firewalld的9个zone以及操作和service的操作

保存以及备份iptalbes规则 设定了的防火墙规则要进行保存,否则系统重启后这些规则就没有了,使用命令 ”service iptables save ” 会把设定好的防火墙规则保存到文件/etc/sysconfig/iptabl...

黄昏残影
昨天
0
0
k8s image

k8s.gcr.io/kube-apiserver-amd64:v1.11.0k8s.gcr.io/kube-controller-manager-amd64:v1.11.0k8s.gcr.io/kube-scheduler-amd64:v1.11.0k8s.gcr.io/kube-proxy-amd64:v1.11.0k8s.gcr.......

分秒
昨天
0
0
数据结构--排序

这篇博客包含了数据结构中多种的排序算法: (1)简单选择:第一趟在A[0]~A[n-1]之间找到最小的,与A[0]进行交换,之后在A[1]~A[n-1]之间进行。。。第i趟在A[i-1]~A[n-1]之间找到最小的,最后...

wangxuwei
昨天
1
0
一名3年工作经验的java程序员应该具备的职业技能

一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、拿到的薪...

老道士
昨天
3
0
MAC安装JDK

一 :在JDK官网下载对应的JDK版本 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 二:找到JDK安装目录,点击会出现图标,双击图标自动安装,勾选默...

WALK_MAN
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部