面试准备
引用
源地址
1.值类型和数据类型
值类型分配在栈上面,而引用类型分配在堆上面,在栈上面存在一个空间,该空间保存堆上面的对象的地址。
2.只有一个对象从代码库的任何部分都不可访问时,垃圾回收器才会从堆中删除它,将在下一次垃圾回收时发生。
3..net垃圾回收器是堆的清洁工,他会压缩空的内存块来实现优化(必要时),为辅助这一行为,托管堆保存这一个指针,它精确的指示下一个对象被分配的位置。
4.托管堆分配内存:
一.计算分配对象所需的总内存数(数据成员和基类)
二.检查托管堆,确保有足够空间,如果空间足够,调用类型构造函数,最终将内存中新对象的引用返回给调用者。如果没有足够空间,将进行垃圾回收。
三.在将引用返回给调用者之前,移动下一个对象的指针,指向托管堆上下一个可用的位置。
5.将对象引用设置为null,并不意味着强制垃圾回收器立即启动,并把对象从对上面移除,只是显示的取消引用和之前所指对象之间的连接。
6.引用程序根
根(root)就是一个存储位置,其中保存着对托管堆上一个对象的引用。在一次垃圾回收过程中,运行库将检查托管堆上的对象,判断应用程序是否仍然可以访问他们,即是否还有根。CLR将建立一个对象图,代表堆上可达的每一个对象,垃圾回收器不会在对象图上让一个对象出现两次。在一次垃圾回收过程中,一个对象被标记为终结后,他们就会从内存中清除,堆上的剩余空间被压缩,CLR修改活动的根的集合执行正确内存位置,下一个对象指针被重新调整。
7.对象的代
第0代:从没有被标记为回收的新分配的对象。
第1代:在上一次垃圾回收中没有被回收的对象
第2代:在一次以上的垃圾回收后仍然没有被回收的对象。
8.强制垃圾回收
通过编程使用GC.Collect()强制垃圾回收,如果你确定让垃圾回收器马上检查不可访问对象可能有好处,就可以显示触发一次垃圾回收。
public void Func3()
{
//…
GC.Collect(0);//并且显示指定回收的代
GC.WaitForPendingFinalizers();
//…
}
9.构建可终结对象
System.Object类定义了名为Finalize()的虚方法。
protected virtual void Finalize(){}
当为自定义的类重写Finalize方法时,就建立了一个地方,来为类型执行必要的清理逻辑。因为这个成员被定义为受保护的,所以不能通过点操作符直接调用该方法。而是在内存中删除这个对象之前,垃圾回收器会调用对象的Finalize()方法。在结构类型上重写Finalize()是不合法的,值类型不分配在堆上,也就不能被回收,但是如果构建的结构包含非托管资源,可以实现IDisposable接口。还有一种情况,当应用程序域从内存中卸载时,CLR自动他的生命周期中创建的每一个可终结对象的终结器。然而大多数类不需要显示的逻辑清理。只有在使用非托管资源时,才可能需要。
在.net凭条中,非托管资源是通过使用PInvoke(平台调用)服务直接调用操作系统的API,或通过一些复杂的COM交互取得。
10.使用终结器语法重写Finalize()方法,这里不能使用预期的override关键字重写Finalize()方法,而是使用终结器语法。
public class FinalizeClass
{
~FinalizeClass()
{
//清理非托管资源
//…
}
}
当在托管堆上分配对象时,运行库自动确定该对象是否提供了一个自定义的Finalize()方法,如果是这样,对象被标记为可终结的,同时指向这个对象的指针被保存在名为终结队列的内部队列中。终结队列是一个由垃圾回收器维护的表,它指向每一个在从堆上删除之前必须被终结的对象。当垃圾回收器确定从内存中释放一个对象的时间时,它检查终结队列上的每一项,并将对象从堆上复制到另一个可称作终结可达表的托管结构上。此时,下一个垃圾回收将产生另一个线程,为每一个终结可达表中的项调用Finalize()方法。这里进行了两次垃圾回收。
11.通过实现IDisposable接口,构建可处置对象。
public Interface IDisposable
{
void Dispose();
}
如果实现这个接口,就是假当对象用户不在使用这个对象时,会在这个对象引用离开作用域之前手工调用Dispose();这样对象可以执行任何必要的非托管资源的清除工作,而不会将对象放在终结队列上导致的性能损失。
public class FinalizeClass:IDisposable
{
public void Dispose()
{
//清除非托管资源
//…
}
}
调用:
public void Func3()
{
//…
GC.Collect();
GC.WaitForPendingFinalizers();
//…
FinalizeClass fcls = new FinalizeClass();
fcls.Dispose();
}
另一种:
//当退出using作用域的时候自动调用fcls2.Dispose();
using (FinalizeClass fcls2 = new FinalizeClass())
{
//
}