1 .net中的托管对象
1>普通对象:即没有使用系统资源的对象,故没有析构函数。
2>使用系统资源的对象:带析构函数并在其中释放系统资源。
*::系统资源à文件,各种流,网络连接,数据库连接等(内存也是系统资源,但这里的系统资源并不包括内存)。
2使用系统资源的5大步骤:
1> 为代表资源的类型分配内存。
2> 初始化资源的状态,请求非内存的系统资源(打开文件,建立数据库连接等)。
3> 通过访问类型的实例及其成员来访问资源。
4> 清空资源状态,释放系统资源。(关闭文件,关闭数据库连接等)。
5> 释放内存。
对于普通对象,只有上面的1>,3>,5>步,而对于使用了系统资源的对象才有上面的全部5步。
CLR默认调用Finalize()来实现第4>步。使用了系统资源的类应该实现Dispose()方法,通过程序员主动调用来释放使用的系统资源,避免CLR调用Finalize()方法带来的性能损失。因为无用内存回收(Garbage Collection 简称GC)运行时,会中止当前程序的执行,大大影响程序的性能。
3引用类型对象在内存中的分配
Class Demo{
Private int x ;
Private int y;
Public Demo(int x,int y)
{
This.x = x;
This.y = y;
}
}
Demo d1 = new Demo(1,2);
Demo d2 = new Demo(3,4);
Demo d3 = new Demo(5,6);
New Demo(1,2)所做的事:
1> 托管堆manage heap 中分配指定类型所需字节空间作为存储其对象内存空间并将该空间清0;
2> 初始化对象的2个附加成员:指向类型方法表的指针和syncBlockIndex指针。
3> 引起对构造函数的调用。
4> 返回指向新建对象的引用。
如图:
4CLR GC内存分配
当对象过多,manage heap分配光了或者不足分配新的对象时,CLR启动 GC,这时主线程被停止运行。GC将堆中不再被使用的对象占用的内存释放掉,然后整理堆,使剩余空间连续。如果没有可以释放的对象,或者释放了无用对象后内存还是不足,则CLR会抛出一个OutOfMemoryException异常。
5GC如何判断对象不再使用
根:可简单理解为有引用指向他。
简单来说,就是有引用指向他的对象是有用的,而没有引用指向的对象则认为不再使用。