C# 运行时的关系
简介
记录c#对象在托管堆中运行时的相互关系,如下记录了一个方法在执行时候的生命周期,当方法在之前,CLR会先执行将方法里面所有用到的局部变量、参数对应的内存地址等全部存放当前线程栈当中,并且会将所有实例字段设为null或者0,new操作之后才会返回对象的内存地址,。
线程栈
1.CRL在运行的时候会启动一个进程,该进程包含多个线程,线程在进行创建的时候会分配到1MB的栈,栈空间用于向方法传递实参,方法内部定义的局部变量也在栈上。
2.最简单的方法包含初始化代码,在方法开始工作前进行初始化,还包含结束代码,在方法工作后对其进行清理,下图展示了M1方法开始执行的时候,它的初始化代码在线程栈上分配局部变量name的内存,并且会在堆中为name开辟一块内存用来存储name
3.然后执行M2方法,将局部变量name作为实参传递,这里传递的其实是一个引用的地址也就是name变量所在内存中的位置,并且也会将返回地址也存到栈中,被调用的方法在结束之后,应该返回的位置,如下图所示:
4.当方法M2开始执行时,他的初始化代码在线程栈中为局部变量len和count分配内存,当M2方法内部代码执行完成之后,M2开始执行Return语句,造成CPU的指令指针被设置成栈中的返回地址,最终M1也会返回到它的调用者:
类存储
假如现在存在一个类的定义,name现在基于这个类来进行讨论:
public class User{
int age=;
string name="zyz";
public string getUserName(){...} }
当window已经启动,CLR以加载到其中,并且托管堆也已初始化,c#编译器会把C#代码编译成IL(中间语言)并且由CLR当中的JIT把IL代码转换成本机cpu指令, JIT在编译的时候会生成。
在执行的时候M3内部引用的所有类型会注意到包括user,int,string类型,这时CLR要确定定义了这些类型的所有程序及都已经加载,然后利用程序集提取与这些类型相关的信息,创建一些数据结构来表示类型本身。如下图所示:
当CLR确认方法当中所有类型都已经创建,M3代码编译之后就允许线程执行M3的代码,M3的构造函数执行时必须在线程栈中为局部变量分配内存,
当实例化User的时候,将会在托管堆中创建user类型的一个实例,并且该实例也有类型对象指针和同步块索引,该对象还包含了必要的字节来容纳user类型定义的所有数据字段(age,name),以及容纳由user的任何积累(本例只有Object,所有对象都继承system.object)定义的所有字段,任何时候在堆上新建对象,CLR都自动初始化内部的类型对象指针成员来引用和对象对应的类型对象。
当调用M3方法当中进行调用getUserName的时候,会对方法进行JIT编译,在调用JIT编译好的代码。
如有理解有误的地方,还请给与指正!~
C# 运行时的关系的更多相关文章
- .NET中 类型,对象,线程栈,托管堆在运行时的关系
.NET中 类型,对象,线程栈,托管堆在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and T ...
- [读书心得] .NET中 类型,对象,线程栈,托管堆在运行时的关系
.NET中 类型,对象,线程栈,托管堆 在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and ...
- 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法(第二次修改)
1.线程栈 window的一个进程加载clr.该进程可能含有多个线程,线程创建的时候会分配1MB的栈空间. 如图: void Method() { string name="zhangsan ...
- C# 类型、对象、线程栈和托管堆在运行时的关系
我们将讨论类型.对象.线程栈和托管堆在运行时的相互关系,假定有以下两个类定义: internal class Employee { public int GetYearsEmplo ...
- .Net 类型、对象、线程栈、托管堆运行时的相互关系
JIT(just in time)编译器 接下来的会讲到方法的调用,这里先讲下JIT编译器.以CLR书中的代码为例(手打...).以Main方法为例: static void Main(){ Cons ...
- C# (类型、对象、线程栈和托管堆)在运行时的相互关系
在介绍运行时的关系之前,先从一些计算机基础只是入手,如下图: 该图展示了已加载CLR的一个windows进程,该进程可能有多个线程,线程创建时会分配到1MB的栈空间.栈空间用于向方法传递实参,方法定义 ...
- 【.Net基础一】 类型、对象、线程栈、托管堆运行时的相互关系
目前在看CLR via C#,把总结的记下来,索性就把他写成一个系列吧. 1.[.Net基础一] 类型.对象.线程栈.托管堆运行时的相互关系 2.[.Net基础二]浅谈引用类型.值类型和装箱.拆箱 J ...
- Android ART运行时无缝替换Dalvik虚拟机的过程分析
Android ART运行时无缝替换Dalvik虚拟机的过程分析 分类: Android2014-01-13 00:59 42722人阅读 评论(66) 收藏 举报 AndroidARTDalvikV ...
- 【VS开发】MFC运行时库与debug、release版本之间的配置关系
参考内容: 前段时间从网上下来一个有意思的代码,用VS2010打开时需要将工程转换为2010的工程,转化后却出现了编译不通过的问题,类似这样的错误:c:\program files\microsoft ...
随机推荐
- 机器学习pipeline总结
# -*- coding: utf-8 -*- """scikit-learn introduction Automatically generated by Colab ...
- 利用Azure虚拟机安装Dynamics 365 Customer Engagement之一:准备工作
我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...
- OC代码规范小记
代码规范 一:基本代码命名 1.通用原则 尽量清晰又简洁,无法两全时清晰更重要,可读性优先级更高. insertObject:atIndex: 好的 insert:at 坏的 removeObject ...
- 个人项目-WC(C/C++ 兼容Linux和Windows)
一.Github地址 https://github.com/S-TRAVELER/WC 实现的功能: 支持 -c 支持 -w 支持 -l 支持 -s 支持 -a 图形界面 多参数(文件名或通配符表达式 ...
- 通过Shell脚本来创建批量服务器上的MySQL数据库账号
1.项目背景 因监控需要,我们需要在既有的每个MySQL实例上创建一个账号.公司有数百台 MySQL 实例,如果手动登入来创建账号很麻烦,也不现实.所以,我们写了一个简单的shell脚本,用来创建批量 ...
- mysql5.7 Multiple-Column Indexes 多列索引(二)
场景一: 复合索引的替代方法,对多列字段拼接做hash,引入一个hashed 字段,对此字段添加索引,可以做到复合索引查询速度快,例: SELECT * FROM tbl_name WHERE has ...
- 网络编程~~~ socket(套字节)
一 socket (套接字) socket处于应用层与传输层之间,提供了一些简单的接口,避免与操作系统之间的对接,省去了相当繁琐复杂的操作. socket在python中属于一个模块,通过调用模块中已 ...
- django验证码captcha
官方文档 https://django-simple-captcha.readthedocs.io/en/latest/usage.html#installation 使用命令安装pip instal ...
- 【转】Cookie和Session和Cache
1 Cookie和Session Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力. Session可以用Cookie来实 ...
- nginx学习(四):nginx处理web请求机制
worker抢占机制 如下图所示,如果有一个请求,各个work进程会进行争锁.谁抢到是谁的.需要注意Nginx 所有worker进程协同工作的关键(共享内存). [accept_mutex的介绍] 当 ...