• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#运行时相互关系浅析

C#运行时相互关系浅析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c站,c语言,欲情 c max,奔驰c200,85度c等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文主要讲述运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别,以及内存的分配和回收。

线程栈:在一个进程中可能包含多个线程,一个线程在创建的时候,会分配到一个大小1MB大小的栈,栈用于存储方法的实参、形参以及方法内部的局部变量,栈是从高位内存地址向地位地址构建的,由于栈有先进后出的特点,所以先定义的变量后被回收。

下面来看一个简单的例子,让你更了解线程栈

由于线程栈是从高位开始分配内存,先分配的我就画在上面了,在调用F1();方法时,分配内存的顺序是:name->n->F2的返回地址->Age->name;回收内存的顺序当然是反过来的。在一个方法中,应该包含一些序幕代码,进行一些初始化工作,还有一些尾声代码,等方法执行完成之后做一些回收工作。由于方法的返回地址先分配,在方法执行完成的时候回到返回地址,递归太深就容易出现栈溢出,请看我的《递归再一次让哥震惊了》,因为参数、局部变量都必须等到方法返回的时候才能回收。

在介绍托管堆之前先看看两个简单的类:

publicclassPerson 
{ 
privateintheight; 
publicvoidSetHeight(intheight) 
{ 
this.height = height; 
} 
publicvirtualvoidSay(stringword) { } 
publicstaticstringHead() 
{ 
return"my head"; 
} 
publicstaticintAge = 100; 
} 
publicclassStudent : Person 
{ 
publicoverridevoidSay(stringword) 
{ 
Console.WriteLine(word); 
} 
} 
</div>

 

staticvoidMain(string[] args) 
{ 
Person student = newStudent(); 
student.Say("Hello cth"); 
student.SetHeight(172); 
Person.Head(); 
Console.ReadLine(); 
} 
</div>

CLR会在第一次访问一个对象时加载该对象,在这里,定义变量student时会为Person对象在线程栈中分配内存,第一次加载吗,在构造一个Student对象之前先要加载Student对象,并为Student类型对象分配内存,并构建一个Student对象。对象的地址存入线程栈中的局部变量student 中,我们知道类型对象的内容包含:类型对象指针、同步索引块、静态字段和方法(静态的和非静态的),不管是类型对象、还是实例类型都必须有类型对象指针、同步索引块;我们知道静态字段属于类,被这个类的所有实例共享,当然静态字段的内存是在类型本身中分配的,方法也是类的所有实例共享的,他的内存也是在类型本身中分配的,在每一个类型对象中都有一个方法表,类中定义的方法都有一个对应的项。

在构造一个对象的实例时,只需要为类型对象指针、同步索引块、该对象的实例字段分配内存,对于对象实例来说,类型对象指针可以让实例访问类型对象中德静态字段、方法等。

Student是线程栈中的定义的一个局部变量,保存Student的一个实例的在托管堆中的地址,所以他可以访问Student对象中的字段,方法,其实访问方法是通过类型对象指针访问类型对象Student中的方法表中对象的项。

Say方法的执行过程:变量student指向的是一个Student对象,调用的当然是Student类型对象中的Say方法,尽管在定义student的时候是Person类型,因为他是引用类型,他指向的是托管堆中Student对象的内存,然后遍历该对象的方法表,找到该方法调用。

特别说明虚方法,JIT在虚方法中加了一些额外的代码,方法每次调用的时候都会执行这些代码,这些代码会检查发出调用的变量,然后根据这个变量找到其应用的对象,然后调用这个对象的方法,若没有这些代码,你觉得CLR是调用父类的方法还是调用之类的方法呢,虚方法带来方便的同时,也多了这些必须的检查的代码。

SetHeight方法的执行过程:和Say方法前面是一样,只是在遍历Student对象的方法表时没有找到该方法,我们知道父类中定义的非private方法都可以被子类继承,是因为每个类型都定义了一个字段引用了他的基类,如果一个类调用的方法那个方法不是自己定义的,那么编译器会回溯类层次结构,一直到基类Object,找到相关的方法并调用,如果没有找到相关的方法就报了异常呗。所以SetHeight方法其实调用的是Person中的SetHeight方法。

Head方法的执行:由于Head方法是静态方法和上面两个方法有所不同,调用静态方法的时候,CLR会定位与静态方法对象的类型对象,然后在对应实例对象对象的方法表中查找相关的记录项,如果没有找到,同样会回溯。

当执行完student.SetHeight(172);时,student在也没有被引用,成为垃圾,在其所在的方法返回之前将会被回收,也就是说student实例对象被回收,释放其所在的内存,而类型对象不会被回收,类型对象的生成周期是:对象被加载到CLR中,直到其所在的AppDomain卸载。静态字段是他所引用类型的跟,所以被静态类型引用的对象永远不会被回收,如果其引用的是一个集合对象,并向其中不断的加入元素的话,就会造成内存泄露。

以上就是关于C#运行时相互关系的全部内容,希望对大家的学习有所帮助。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C# 检索不区分大小写并高亮显示实例详解
  • C#实现Base64处理的加密解密,编码解码示例
  • C# SqlHelper应用开发学习
  • C#多线程经典示例(吃苹果)
  • C#使用Windows Service的简单教程(创建、安装、卸载、调试)
  • C# 6.0 的知识梳理
  • C#向PPT文档插入图片以及导出图片的实例
  • C#使用Jquery zTree实现树状结构显示 异步数据加载
  • C#清理非托管对象实例分析
  • C#双缓冲技术实例详解

相关文章

  • 2017-05-28在Unity中实现简单的伪时间同步
  • 2017-05-28c#目录操作示例(获取目录名称 获取子目录)
  • 2017-05-28C# Socket粘包处理讲解示例
  • 2017-05-28C#生成指定范围内的不重复随机数
  • 2017-05-28直接在线预览Word、Excel、TXT文件之ASP.NET
  • 2017-05-28C#实现的json序列化和反序列化代码实例
  • 2017-05-28C#调用windows api关机(关机api)示例代码分享
  • 2017-05-28C#使用加边法计算行列式的值
  • 2017-05-28C#一个简单的定时小程序实现代码
  • 2017-05-28浅谈C#手机号换成111XXXX1111 这种显示的解决思路

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • extern外部方法使用C#的实现方法
    • C#实现带消息数的App图标
    • WinForm中comboBox控件数据绑定实现方法
    • 测试stringbuilder运行效率示例
    • .net2.0+ Winform项目实现弹出容器层
    • C# FileStream读写的文本操作代码分析
    • C#静态static的用法实例分析
    • c#文件操作示例带详细注释
    • C#控制IE进程关闭和缓存清理的实现代码
    • C#索引器介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有