.NET对象的创建、垃圾回收、非托管资源的手动处理

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: 小  |  中  |  大  |  超大  

.NET对象的创建、垃圾回收、非托管资源的手动处理本篇用来梳理对象的创建、垃圾的回收,以及非托管资源的手动处理。

→首先运行应用程序,创建一个Windows进程。

→CLR创建一块连续的虚拟地址空间,这个地址空间就是托管堆。而且,这个地址空间最初并没有对应的物理存储空间。

虚拟地址空间分成2段。一个区段是普通堆,也叫GC堆,大小小于85000字节的引用类型对象的实例被分配在这里;另一个是大对象堆,大小大于等于85000字节的引用类型对象的实例被分配在这里。

对于客户端应用程序,每个区段的大小大致是16MB;对于服务端应用程序,每个区段的大小大致是64MB。另外,每个区段的大小还会因CPU的数量,是否是32位或64位操作系统而各异。

随着每个区段被装满对象,CLR会分配更多的区段,直到整个进程空间都满了为止,每个进程可使用4GB的内存。

托管堆上维护着一个指针NextObjPtr,指向下一个对象在托管堆上分配的位置。

托管堆根据存储信息的不同分为垃圾回收堆GC Heap和加载堆Loader Heap。垃圾回收堆GC Heap存储对象实例,受GC管理;加载堆Loader Heap存储AppDomain中的元数据信息,例如基类型、静态字段、静态方法、接口信息等,不受GC管理,它的生命周期从创建AppDomain开始到卸载AppDomain结束。此时,托管堆以及其它方面大致是这样分布的:

→在托管堆上创建对象

□ 引用类型对象创建

使用new关键字创建引用类型对象。

FileStream fs = new FileStream(@"",FileMode.Open);

以上代码经编译器编译,在生成的中间IL代码中实际上是一个newobj指令。IL相关的指令还包括:ldstr指令用于创建string类型对象,newarr用于分配新的数组对象,box指令用于在值类型转换为引用类型时,将值类型字段拷贝到托管堆上。

通过以下代码来体会托管堆上创建对象的大致过程:

public class Employee

{

PRivate int _id;

private Status _status;

public Employee()

{

_id = 1;

_status = new Status();

}

}

public class Sales : Employee

{

public bool _isLive;

public bool IsLive()

{

return _isLive;

}

public static void Main()

{

Sales _sales;

_sales = new Sales();

_sales._isLive = true;

Console.WriteLine(_sales.IsLive());

}

}

public class Status

{

private int _years;

private char _level = "A";

}

1、执行Sales _sales,在线程堆栈上开辟4byte的内存空间,用于保存Sales对象的托管堆地址,此时为null。

2、_sales = new Sales(),递归

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航