c#源码的执行过程详解
要讲到C#源码的执行过程 首先要提下程序集,因为Clr并不是和托管摸块打交道的,而是和程序集(dll,exe)
1、从哪里来
程序集是由一个或者多个托管模块以及 资源文件等共同组成的,C#编译器(csc.exe)再把源码编程成IL代码和元数据的时候,会进一步连同资源文件合并成程序集,
实际上就是个PE32文件,里面包含一个清单文件 和多个托管模块和资源(如图),另外程序集中还有一些自描述信息。
2、执行过程
编译器生成好程序集以后,如果是可执行的程序集,会在Main方法执行之前,window会预先读取程序集的头文件(pe32),如果是x86则开一个32位的进程,x64的就开一个64位的进程
然后在进程空间里面加载MSCOREE.DLL的x86 或者x64版本或者arm版本,然后进程的主线程会调用MSCOREE.DLL的一个方法,初始化Clr,而Clr会加载程序集exe,再调用其入口方法Main。
3.Main方法内部执行
在Main执行之前,Clr 会检测出方法引用的所有类型,(Console),然后在内存中分配对应数据类型的空间,这个地址里面包含着这个类型所有的方法声名,每一项都对应着Clr里面的一个未编档函数(JITCompiler)
首次运行Main方法的试试JITCompiler会被调用,在这个方法里面1,负责在方法的实现类型中(console)程序集元数据中查询该方法的IL方法 2,动态分配内存块 3,把IL编译成本机Cpu的指令,存储到动态分配的空间里面
4,修改这个条目的地址,使它指向动态分配的地址 5.跳转到内存块中的本机代码执行,这时候执行的就是IL代码的cpu机器码
5.在次执行Console.WriteLine的时候,就不会运行JITCompiler,直接运行机器码
相关推荐
-
C#执行存储过程并将结果填充到GridView的方法
本文实例讲述了C#执行存储过程并将结果填充到GridView的方法.分享给大家供大家参考,具体如下: SelectSql sq = new SelectSql(); SqlConnection conn = new SqlConnection(sq.lc); conn.Open(); SqlDataAdapter rd = new SqlDataAdapter(); DataSet ds=new DataSet(); SqlCommand sqlcom = new SqlCommand("dbo
-
C#中实现一次执行多条带GO的sql语句实例
本文实例讲述了C#中实现一次执行多条带GO的sql语句.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Text.RegularExpressions; using System.Data.SqlClient; namespace ConsoleApplicati
-
C#计算程序执行过程花费时间的方法
本文实例讲述了C#计算程序执行过程花费时间的方法.分享给大家供大家参考.具体如下: 计算执行完程序花费的时间: void AddInfo() { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < 1000; i++) { Console.WriteLine(i.ToString()); System.Threading.Thread.Sleep
-
C#实现程序等待延迟执行的方法
本文实例讲述了C#实现程序等待延迟执行的方法.分享给大家供大家参考.具体如下: [System.Runtime.InteropServices.DllImport("kernel32.dll")] static extern uint GetTickCount(); /// <summary> /// 程序等待延迟执行 /// </summary> /// <param name="ms"></param> stati
-
C#利用Task实现任务超时多任务一起执行的方法
前言 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建. 如下代码所示 1.使用构造函数创建Task Task t1 = new Task(MyMethod); 2.使用Task.Factory.StartNew 进行创建Task Task t1 = Task.Fact
-
C#执行外部命令的方法
本文实例讲述了C#执行外部命令的方法.分享给大家供大家参考.具体实现方法如下: ///<summary> ///executes a system command from inside csharp ///</summary> ///<param name="cmd">a dos type command like "isql ..."</param> ///<param name ="millsec
-
C#动态编译并执行字符串样例
本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 using System; using Microsoft.CSharp; using System.CodeDom.Compiler; class Program { public static void Main() { // The C# code to execute string code = "using System; " + "using System.IO; "
-
c#源码的执行过程详解
要讲到C#源码的执行过程 首先要提下程序集,因为Clr并不是和托管摸块打交道的,而是和程序集(dll,exe) 1.从哪里来 程序集是由一个或者多个托管模块以及 资源文件等共同组成的,C#编译器(csc.exe)再把源码编程成IL代码和元数据的时候,会进一步连同资源文件合并成程序集, 实际上就是个PE32文件,里面包含一个清单文件 和多个托管模块和资源(如图),另外程序集中还有一些自描述信息. 2.执行过程 编译器生成好程序集以后,如果是可执行的程序集,会在Main方法执行之前,window会预
-
Django 源码WSGI剖析过程详解
前言 python 作为一种脚本语言, 已经逐渐大量用于 web 后台开发中, 而基于 python 的 web 应用程序框架也越来越多, Bottle, Django, Flask 等等. 在一个 HTTP 请求到达服务器时, 服务器接收并调用 web 应用程序解析请求, 产生响应数据并返回给服务器. 这里涉及了两个方面的东西: 服务器(server)和应用程序(application). 势必要有一个合约要求服务器和应用程序都去遵守, 如此按照此合约开发的无论是服务器还是应用程序都会具有较大
-
Redis源码环境构建过程详解
Redis源码环境构建 近日,蒋德钧新上了一门Redis源码剖析的课程,应好友沈架构师的邀请,又重拾起了Redis源码学习.不过作为正经的JAVA工程师,大概在大学毕业后再也没写过C语言的源码了(还是看过一些的).搭建一个Redis阅读环境我都好意思写一篇博客记录一下了. 不过,不是在windows环境下构建了,是在deepin系统下进行的构建,也许windows用户可以出门右拐了.本次搭建环境主要参考以下两篇windows搭建环境的博客: https://juejin.cn/post/
-
Python字节码与程序执行过程详解
目录 问题: 1. 执行过程 2. 字节码 3. 源码编译 三种编译模式: 4. PyCodeObject 5. 反编译 6. pyc 问题: 我们每天都要编写一些Python程序,或者用来处理一些文本,或者是做一些系统管理工作.程序写好后,只需要敲下python命令,便可将程序启动起来并开始执行: $ python some-program.py 那么,一个文本形式的.py文件,是如何一步步转换为能够被CPU执行的机器指令的呢?此外,程序执行过程中可能会有.pyc文件生成,这些文件又有什么作用
-
python源码剖析之PyObject详解
一.Python中的对象 Python中一切皆是对象. ----Guido van Rossum(1989) 这句话只要你学过python,你就很有可能在你的Python学习之旅的前30分钟就已经见过了,但是这句话具体是什么意思呢? 一句话来说,就是面向对象中的"类"和"对象"在Python中都是对象.类似于int对象的类型对象,实现了"类的概念",对类型对象"实例化"得到的实例对象实现了"对象"这个概念.
-
Vue3 源码解读静态提升详解
目录 什么是静态提升 transform 转换器 hoistStatic 静态提升 walk 函数 walk 函数流程图 总结 什么是静态提升 静态提升是Vue3编译优化中的其中一个优化点.所谓的静态提升,就是指在编译器编译的过程中,将一些静态的节点或属性提升到渲染函数之外.下面,我们通过一个例子来深入理解什么是静态提升. 假设我们有如下模板: <div> <p>static text</p> <p>{{ title }}</p> </di
-
nginx源码分析线程池详解
nginx源码分析线程池详解 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,nginx为什么不采用多线程模型(这个除了之前一篇文章讲到的情况,别的只有去问作者了,HAHA).其实,nginx代码中提供了一个thread_pool(线程池)的核心模块来处理多任务的.下面就本人对该thread_pool这个模块的理解来跟大家做些分享(文中错误.不足还请大家指出,谢谢) 二.thread_
-
Vue编译器源码分析compileToFunctions作用详解
目录 引言 Vue.prototype.$mount函数体 源码出处 options.delimiters & options.comments compileToFunctions函数逐行分析 createFunction 函数源码 引言 Vue编译器源码分析 接上篇文章我们来分析:compileToFunctions的作用. 经过前面的讲解,我们已经知道了 compileToFunctions 的真正来源你可能会问为什么要弄的这么复杂?为了搞清楚这个问题,我们还需要继续接触完整的代码. 下面
-
Java源码解析之TypeVariable详解
TypeVariable,类型变量,描述类型,表示泛指任意或相关一类类型,也可以说狭义上的泛型(泛指某一类类型),一般用大写字母作为变量,比如K.V.E等. 源码 public interface TypeVariable<D extends GenericDeclaration> extends Type { //获得泛型的上限,若未明确声明上边界则默认为Object Type[] getBounds(); //获取声明该类型变量实体(即获得类.方法或构造器名) D getGenericDe
-
Java源码解析之GenericDeclaration详解
学习别人实现某个功能的设计思路,来提高自己的编程水平.话不多说,下面进入正题. GenericDeclaration 可以声明类型变量的实体的公共接口,也就是说,只有实现了该接口才能在对应的实体上声明(定义)类型变量,这些实体目前只有三个:Class(类).Construstor(构造器).Method(方法)(详见:Java源码解析之TypeVariable详解 源码 public interface GenericDeclaration { //获得声明列表上的类型变量数组 public T
随机推荐
- Ionic+AngularJS实现登录和注册带验证功能
- 支付宝支付开发IOS图文教程案例
- Python列表list数组array用法实例解析
- java利用htmlparser获取html中想要的代码具体实现
- IOS 贝塞尔曲线(UIBezierPath)属性、方法整理
- iOS开发之随机生成两圆之间的标准圆
- php中拷贝构造函数、赋值运算符重载
- asp.net 选择excel类型文件,利用Dos命令成批复制文件
- PHP网页游戏学习之Xnova(ogame)源码解读(五)
- 多字段模糊搜索的函数
- Android NoSuchFieldError解决办法
- javascript中获取元素标签中间的内容的实现方法
- php单文件版在线代码编辑器
- Android编程实现检测当前电源状态的方法
- 浏览器常用高宽的jquery插件
- javascript中setAttribute兼容性用法分析
- 新页面打开实际尺寸的图片
- windows+apache+mod_python配置django运行环境
- 百度最近不收站分析,为什么不收录你的站
- 在Windows版的PHP中使用ADO