每个对象只有在该对象不存在任何引用才会被垃圾回收起回收。

可以调用静态方法System.GC.Collect()垃圾回收器,但是不建议这么做;

用using语句可以有效的自动释放掉资源。

实在没有办法才用从析构函数中调用Dispose方法。 class Example:IDisposable ~example(){ Dispose(); } public virtual void Dispose(); { if(!this.disposed){ try{ //在此释放稀缺资源 } finally{ this.disposed=true; GC.SuppressFinalize(this); } } } public void SomeBehavior()//示例方法 { checkifdisposed(); } ... private void checkifdisposed(){ if(this.disposed) { throw new ObjectDisposedException("Example"); } } private Resource scarce; private bool disposed=false; }

---------------------------------------------------------------------------------------------------------------------

附加C#垃圾回收器的分级回收机制:

C#中的回收器是分代的垃圾回收器(Gererational Garbage Collector) 它将分配的对象分为3个类别或代。(可用GC.GetGeneration方法返回任意作为参数的对象当前所处的代)最近被分配内存的对象被放置于第0代,因为第0代很小,小到足以放进处理器的二级(L2)缓存,所以它能够提供对对象的快速存取。经过一轮垃圾回收后,仍然保留在第

0代中的对象被移进第1代中,再经过一轮垃圾内存回收后,仍然保留在第1代中的对象则被移进第2代中,第2代中包含了生存期较长的对象。

在C#中值类型是在堆栈中分配内存,它们有自身的生命周期,所以不用对它们进行管理,会自动分配和释放。而引用类型是在堆中分配内存的。

所以它的分配和释放就需要像回收机制来管理。

C#为一个对象分配内存时,托管堆可以立即返回新对象所需的内存,因为托管堆类似于简单的字节数组,有一个指向第一个可用内存空间的指针,

指针像游标一样向后移动,一段段内存就分配给了正在运行的程序的对象。

在不需要太多垃圾回收的程序小,托管堆性能优于传统的堆。

当第0代中没有可以分配的有效内存时,就触发了第0代中的一轮垃圾回收,它将删除那些不再被引用的对象,并将当前正在使用的对象移至第1代。而当第0代垃圾回收后依然不能请求到充足的内存时,就启动第1代垃圾回收。如果对各代都进行了垃圾回收后仍没有可用的内存就会引发一个OutOfMemoryException异常。

终结器

在有些情况下,类可以提供一个终结器在对象被销毁时执行,终结器是一个名为

Finalize的受保护的方法:

protected void Finalize()

{

base.Finalize();

//

释放外部资源

}

垃圾回收器使用名为“终止队列”的内部结构跟踪具有

Finalize

方法的对象。每次您的应用程序创建具有Finalize 方法的对象时,垃圾回收器都在终止队列中放置一个指向该对象的项。

托管堆中所有需要在垃圾回收器回收其内存之前调用它们的终止代码的对象都在终止队列中含有项。(实现Finalize 方法或析构函数对性能可能会有负面影响,因此应避免不必要地使用它们。用Finalize 方法回收对象使用的内存需要至少两次垃圾回收。当垃圾回收器执行回收时,它只回收没有终结器的不可访问对象的内存。

这时,它不能回收具有终结器的不可访问对象。它改为将这些对象的项从终止队列中移除并将它们放置在标为准备终止的对象列表中。该列表中的项指向托管堆中准备被调用其终止代码的对象。垃圾回收器为此列表中的对象调用Finalize 方法,然后,将这些项从列表中移除。后来的垃圾回收将确定终止的对象确实是垃圾,因为标为准备终止对象的列表中的项不再指向它们。在后来的垃圾回收中,实际上回收了对象的内存。)

Dispose方法

在不使用终结器时,可以考虑使用Dispose方法,你可以使用这个方法来释放所保存包括的在托管对象引用在内的任何资源。但使用它时需用

GC.SuppressFinalize

来告知运行时这些对

象不需要终结。如下所示

:

public void Dispose()

{

object.Dispose();

dbConnection.Dispose();

GC.SuppressFinalize(this); //

申明不需要终结

}

创建并使用了Dispose方法的对象,就需要使用完该对象之后调用这些方法,最好是在Finally中调用。

//

以下代码演示来自

MSDN

// Design pattern for the base class.

// By implementing IDisposable, you are announcing that instances

// of this type allocate scarce resources.

public class BaseResource : IDisposable

{

// Pointer to an external unmanaged resource.

private IntPtr handle;

// Other managed resource this class uses.

private Component Components;

// Track whether Dispose has been called.

private bool disposed = false;

// Constructor for the BaseResource object.

public BaseResource()

{

// Insert appropriate constructor code here.

}

// Implement IDisposable.

// Do not make this method virtual.

// A derived class should not be able to override this method.

public void Dispose()

{

Dispose(true);

// Take yourself off the Finalization queue

// to prevent finalization code for this object

// from executing a second time.

GC.SuppressFinalize(this);

}

// Dispose(bool disposing) executes in two distinct scenarios.

// If disposing equals true, the method has been called directly

// or indirectly by a user's code. Managed and unmanaged resources

// can be disposed.

// If disposing equals false, the method has been called by the

// runtime from inside the finalizer and you should not reference

// other objects. Only unmanaged resources can be disposed.

protected virtual void Dispose(bool disposing)

{

// Check to see if Dispose has already been called.

if (!this.disposed)

{

// If disposing equals true, dispose all managed

// and unmanaged resources.

if (disposing)

{

// Dispose managed resources.

Components.Dispose();

}

// Release unmanaged resources. If disposing is false,

// only the following code is executed.

CloseHandle(handle);

handle = IntPtr.Zero;

// Note that this is not thread safe.

// Another thread could start disposing the object

// after the managed resources are disposed,

// but before the disposed flag is set to true.

// If thread safety is necessary, it must be

// implemented by the client.

}

disposed = true;

}

// Use C# destructor syntax for finalization code.

// This destructor will run only if the Dispose method

// does not get called.

// It gives your base class the opportunity to finalize.

// Do not provide destructors in types derived from this class.

~BaseResource()

{

// Do not re-create Dispose clean-up code here.

// Calling Dispose(false) is optimal in terms of

// readability and maintainability.

Dispose(false);

}

// Allow your Dispose method to be called multiple times,

// but throw an exception if the object has been disposed.

// Whenever you do something with this class,

// check to see if it has been disposed.

public void DoSomething()

{

if (this.disposed)

{

转载于:https://www.cnblogs.com/yangzhenping/p/3360865.html

面试之C#--垃圾回收器什么时候回收?相关推荐

  1. 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?...

    一.垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?   1.对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址.大小以及使用情况. 通常, ...

  2. 记录java对象修改过的字段_Java垃圾回收器与内存回收策略

    Java中,内存由虚拟机管理,控制着回收什么,什么时候回收,怎么回收. 在栈中内存的随线程产生和分配,销毁而回收,在堆中,需要制定一系列策略来判断该回收哪些区域,以及何时回收. 可达性分析 主流的做法 ...

  3. 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

    对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址.大小以及使用情况.通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象.通过这种方式确定哪些对象是"可达的" ...

  4. 垃圾回收器的作用?垃圾回收器可以马上回收内存吗?

    对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址.大小以及使用情况.通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象.通过这种方式确定哪些对象是"可达的" ...

  5. JVM上篇:内存与垃圾回收篇十四--垃圾回收器

    JVM上篇:内存与垃圾回收篇十四–垃圾回收器 1. GC分类与新能指标 1.1 垃圾回收器概述 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商.不同版本的JVM来实现. 由于JDK的版本处于高 ...

  6. 【搞定Jvm面试】 JVM 垃圾回收揭秘附常见面试题解析

    JVM 垃圾回收 写在前面 本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好 ...

  7. 垃圾回收篇~~垃圾回收器

    1 GC分类与性能指标 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商.不同版本的JVM来实现.由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本. 从不同角度分 ...

  8. 主要垃圾回收器和垃圾回收算法

    垃圾回收算法: 标记清除算法 mark-sweep 分为标记和清除两个阶段,但是内存碎片化严重 复制算法 copying 为了解决内存碎片化问题,但是空间利用率降低,主要用于大量对象存活时间短的年轻代 ...

  9. 垃圾回收③---垃圾回收器

    本篇目录 1.GC的分类与性能指标 1.1 GC分类 1.2 评估GC的性能指标 1.2.1 吞吐量 1.2.2 暂停时间 2.不同垃圾回收器概述 2.1 垃圾收集器发展史 2.2 7款经典的垃圾收集 ...

  10. java 垃圾回收之垃圾回收器篇

    java 垃圾回收之垃圾回收器篇 一,垃圾回收器的分类与性能指标 GC分类 按线程数分(垃圾回收线程数 :可以分为串行垃圾回收器和并行垃圾回收器 串行回收指的是在同一时间段内只允许有一个CPU用于执行 ...

最新文章

  1. Android 不同阶段 Logo 显示
  2. cart2pol函数
  3. 【图像分割模型】全景分割是什么?
  4. Spring Cloud实战小贴士:Zuul统一异常处理(一)
  5. Activiti 流程查询出的结果封装为 JSON 时出现的异常
  6. c语言文件操作函数(未完待续)
  7. python oop 继承_关于oop:使类数据在python中可继承的正确方法是什么?
  8. android 边框重叠,android - Android:recyclerview中的viewitems轮廓与recyclerview边框重叠 - 堆栈内存溢出...
  9. 24、List三个子类的特点
  10. “为爱尖叫”,爱奇艺的晚会聚能术与商业价值释放场
  11. Day 177/200 React 颜色选择器
  12. 浅论bitset与位图算法bitmap
  13. 网络计算机amd,AMD多屏显示设置指南_计算机硬件和网络_IT /计算机_信息
  14. 域用户指定计算机,什么是AD域,如何设置AD域用户仅登录到指定的计算机
  15. 蓝桥杯历年试题汇总 C/C++ B组
  16. AlexNet VGGNet ResNet 对比 简介
  17. Elastic Search:(二)分词器
  18. java try with_Java使用try-with
  19. 市场经济下的“按劳分配”
  20. R语言使用car包的vif函数计算方差膨胀因子,并基于方差膨胀因子开方后和阈值(2)的判断来确认模型特征(预测变量)之间是否存在多重共线性(Multicollinearity)

热门文章

  1. 对因果报应和轮回的态度
  2. 管理感悟:掌握写文档的技能
  3. boost python实现_Boost Python官方样例(一)
  4. c++ 14 新特性
  5. go 变量大写_和我一起学Go系列:Go基本语法概览
  6. 查询数据总数_Web | Django 与数据库交互,你需要知道的 9 个技巧
  7. string类的函数
  8. [转]find命令之exec
  9. NGINX 4xx 5xx 状态码构造
  10. activiti学习资料(架构描述)