.NET程序的编译和运行

程序的编译和运行,总得来说大体是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最后在本地操作系统运行。

下图为传统代码编译运行过程:

.NET的编译和运行过程与之类似,首先编写好的源代码,然后编译为微软中间语言代码,运行的时候即时编译为本地机器语言,同时.NET代码运行时有一个CLR环境来管理程序。如下图为.NET代码编译运行过程:

下面详细介绍下编译运行时的一些概念。
1.MSIL和JIT
在编译使用.NET 框架创建的代码时,不是立即创建操作系统特定的本机代码,而是把代码编译为微软中间语言(Microsoft Intermediate 
Language,MSIL)代码,这些MSIL代码不专用于任何一种操作系统,也不专用于任何一种语言,有些类似于JAVA的字节码。C#及其他.NET语言,如VB.NET在编译阶段都编译为这种语言。
因为代码在编译阶段没有直接编译成本机代码,所以在执行应用程序时,必须完成更多的工作,这就是Just—In-Time(JIT)编译器的任务。
JIT把MSIL编译为专用于某种操作系统和目标机器结构的本机代码,只有这样,操作系统才能执行应用程序。这里编泽器的名称Just—In—Time,反映了MSIL仅在需要时才编译的特性。
过去,常常需要把代码编译为几个应用程序,每个应用程序用于特定的操作系统和CPU结构,这通常是一种优化形式(例如,为了让代码在AMD芯片上运行将更快),但更多时候是必须的(例如分别运行在Windows和Linux操作系统上)。现在就不必要了,顾名思义,JIT编译器使用MSIL代码,而MSIL代码是独立于机器、操作系统和CPU的。目前有几种JIT编译器,每种编译器都用于不同的结构,我们总能找到一个合适的编译器创建所需的本机代码。这样,用户需要做的工作就比较少了,实际上,用户不必考虑与系统相关的细节,只需要把注意力放在代码的功能上就足够了。

2.程序集
在编译应用程序时,创建的MSIL代码存储在一个程序集中,程序集包括可执行的应用程序文件(这些文件可以直接在Windows上运行,不需要其他程序,其扩展名为.exe)和其他应用程序使用的库(其扩展名是.dll)。

除了包含MSIL外,程序集还包含元数据(即程序集中包含的数据信息)和可选的资源(MSIL使用的其他数据,例如声音和图片文件)。在程序集包含的所有文件中,有一个文件用于保存清单。(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件)。需要注意的是一个程序集只能一个程序清单。

元数据允许程序集是完全自我描述的,不需要其他信息就可以使用程序集。也就是说,我们不再需要把应用程序所需要的数据添加到系统注册表中,因此,部署应用程序就非常简单了,只需把文件复制到远程计算机中的目录下即可。

当然,不必把运行应用程序所需要的所有信息都安装到一个地方。我们可以编写一些程序集,执行多个应用程序所要求的任务。此时,通常把这些可重用的程序集放在所有应用程序都可以访问的地方。在.NET
框架中,这个地方是“全局程序集高速缓冲存储器”(Global Assembly cache),有相应的工具可以帮助把程序集放在高速缓冲存储器中。

http://hovertree.com/menu/csharp/

3.托管代码

在把代码编译为MSIL,再用JIT编译器把它编译为本机代码后,CLR的任务还没有完全完成。用.NET 
框架编写的代码在执行时是托管的,即CLR管理着应用程序,其方式是管理内存、处理安全性,以及允许进行跨语言调试等。相反,不在CLR控制之下运行的应用程序是非托管的,某些语言如C++可以用于编写这类应用程序,例如,访问操作系统的低级功能。使用C#主要编写在托管环境下运行的代码,它们使用CLR的托管功能,让.NET自己与操作系统进行交互,当然也可以编写在非托管环境下运行的代码,但需要特别标注。托管代码的优点有:1、平台无关性,2、提高性能,3、语言的互操作性。

4.垃圾回收

托管代码最重要的一个功能是垃圾回收(Garbage 
Collection),它可确保应用程序不再使用某些内存时,这些内存就会被完全释放。在.NET推出以前,这项工作主要由程序员负责,代码中的几个简单错误会把大块内存分配到错误的地方,使这些内存神秘失踪。这通常意味着计算机的速度逐渐减慢,最终导致系统崩溃。

.NET无用存储单元收集器会频繁检查计算机内存,从中删除不再需要的内容。它可能一秒钟内会进行上千次的检查,也可能几秒钟检查一次,或者随时进行检查,但可以肯定的是进行了检查。

5.应用程序域

在以前传统的开发中我们都知道,一个应用程序对应一个进程,并为该进程指定虚拟内存,由操作系统来映射实际的物理内存,有效的维护了进程之间的安全性。但另一方面,每一个进程都会消耗一定的系统资源,降低了性能,并且进程间的通信也比较麻烦。
在.Net中推出了一个新的概念:应用程序域(AppDomain)。可以理解成很多应用程序域都可以运行在同一个.NET的进程中,可以降低系统消耗,同时不同的域之间互相隔离,在安全性方面有保障。另外对于同一个进程内不同域之间的通信也相对简单一点。

转自:http://hovertree.com/h/bjaf/i550eyyq.htm

推荐:http://www.cnblogs.com/roucheng/p/3521864.html

时间: 2024-12-16 01:04:21

.NET程序的编译和运行的相关文章

DOS环境下含包并引用第三方jar的java程序的编译及运行

DOS环境下含包并引用第三方jar的java程序的编译及运行 1.程序目录机构 bin:class文件生成目录 lib:第三方jar包目录 src:源程序文件目录 2.程序代码: 3.程序编译 javac –classpath .;..\lib\commons-lang-2.3.jar -d ..\bin com\Test.java 4.编译后的程序目录: 5.运行程序及结果显示 java -classpath .;..\lib\commons-lang-2.3.jar com.Test

java程序的编译与运行------------------学习笔记(一)

  这里非常粗略的写一下大致过程(如有错误的地方,请及时联系博主^_^) 1.java程序的编译 ①编译器将源文件(*.java)编译成字节码文件( *.class). java编译器会根据classpath路径找到对应的java文件(不存在,则报错),如果该类不依赖其他类,则直接将该类编译成.class文件,如若依赖其他类, 依赖的类已编译,则直接引用,否则先编译被依赖的类,再编译本类. 编译后的字节码文件主要包括字节:常量池和方法字节码; 常量池:存放 代码出现过的所有token(包名,类名

Java程序的编译与运行

Java程序的编译 首先写好一个java程序后需要运行(文件保存名为以.java结尾的文件称之为源文件,源文件里面所编写的代码叫做源代码) 这个.java结尾的文件是不能直接运行的,需要使用javac.exe命令编译成以.class结尾的文件 Java编译器将我们编写的java源文件加载,然后去检查源码里面的语法,如果出现了语法错误会进行提示,这个阶段提示的错误我们称之为编译错误.如果遇到了编译错误,是不会生成.class文件的, 遇到编译错误时,需要我们根据错误提示的信息去分析和解决. 在cm

Java与C++程序在编译和运行上的区别

Java.C++都属于高级语言,而计算机能认识执行的只是机器码(即二进制),所以高级语言都必须经过直接或间接的转换成汇编以后,才能运行: 对于C/C++这类高级计算机语言,它们的编译器(例如Unix下的CC命令.Windows下的CL命令)都是可以把源码直接编译成计算机可以认识的机器码,如exe.dll之类的文件,然后直接运行 而Java语言的跨平台性是它最大的特点之一,这就达成了Java程序平台无头性,因此也有一定的牺牲就是多了一个中间过程,先将Java源程序编译成class文件[字节码形式]

.NET概念:.NET程序编译和运行

.NET概念:.NET程序编译和运行 分类: c#程序设计 2012-02-29 15:46 3001人阅读 评论(2) 收藏 举报 .net编译器语言microsoftassemblyvb.net 程序的编译和运行,总得来说大体是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最后在本地操作系统运行. 下图为传统代码编译运行过程: .NET的编译和运行过程与之类似,首先编写好的源代码,然后编译为微软中间语言代码,运行的时候即时编译为本地机器语言,同时.NET代码运行时有一个CLR环境来

linux下junit测试用例编译与运行配置

1.linux下Java程序的编译与运行 linux 下编译Java代码的command line模式: javac -cp .:./lib/sequoiadb.jar ./com/sequoiadb/test/CsAndClOperation.java linux 下编译Java代码的command line模式: java -cp .:./lib/sequoiadb.jar com.sequoiadb.test.CsAndClOperation 2.linux下Junit测试用例的编译与运行

ZT : JAVA和JAVAC 命令行;java 带有包名编译并运行,附带外部依赖jar包运行

ZT: https://blog.csdn.net/just3do/article/details/68957618 有时候写个小测试,不想开idea,就用cmder,但是老忘记怎么编译,就copy别人的一份博客. javac和java命令行中的-classpath选项 这是个很基础的问题,但是因为基本上都是用现有的IDE工具 来开发java程序,所以很少有人意识到这一点.javac-classpath,设定要搜索类的路径,可以是目录,jar文件,zip文件(里面都是class文件),会覆盖掉所

C语言学习笔记之第一个C程序及编译运行(一)

一.第一个C程序 1>C程序由函数构成 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”.所以,你可以说C语言程序是由函数构成的. 2>C程序的入口 C程序的入口是一个名字叫做main的函数,简称main函数.(为了区分函数,每一个函数都有一个名称)也就是说,不管整个程序中有多少个函数,都是先执行main函数.不管main函数写在文件中间,还是文件末尾,也都是先执行main函数. 注意: 如果一个C程序中没有main函数,那么

MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误

今天照着孙鑫老师的VC++教程学习文件的操作,VS2010,单文档应用程序,项目文件命名为File,也就有了自动生成的CFileDoc.CFileView等类,一进去就编译运行(就是最初自动生成的项目),编译通过,可运行时直接弹出错误框,有点小懵,,,啥都没做就给我看这个: 图一   错误提示框 后来搜索一查,网上好多类似的错误以及解决方案,几乎都试了个遍,有: 方法(1)-重新生成解决方案,或者将项目文件目录下Debug文件夹删了,重新生成Release版: 方法(2)-可以先声明一个临时的C