关于.net的一些基础知识(一)
一、GC工作原理:
GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡的哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理。为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.net CLR,Java VM和Rotor都是采用的Mark Sweep算法。
Mark Sweep:
在程序运行的过程中,不断的把Heap的分配空间给对象,当Heap的空间被占用到不足 以为下一个对象分配的时候Mark Sweep算法被激活,将垃圾内存进行回收并将其返回到free list中。
Mark Sweep就像它的名字一样在运行的过程中分为两个阶段,Mark阶段和Sweep阶段。Mark阶段的任务是从root出发,利用相互的引用关系遍历整个Heap,将被root和其它对象所引用的对象标记起来。没有被标记的对象就是垃圾。之后是Sweep阶段,这个阶段的任务就是回收所有的垃圾。
Mark Sweep算法虽然速度比Reference Counting要快,并且可以避免循环引用造成的内存泄漏。但是也有不少缺点,它需要遍历Heap中所有的对象(存活的对象在Mark阶段遍历,死亡的对象在Sweep阶段遍历)所以速度也不是十分理想。而且对垃圾进行回收以后会造成大量的内存碎片。
Generation:
Generational garbage collector(又被称为ephemeral garbage collector)是基于以下几个假设的:
l 对象越年轻则它的生命周期越短;
l 对象越老则它的生命周期越长;
l 年轻的对象和其它对象的关系比较强,被访问的频率也比较高;
l 对Heap一部分的回收压缩比对整个Heap的回收压缩要快。
Generation的概念就是对Heap中的对象进行分代(分成几块,每一块中的对象生存期不同)管理。当对象刚被分配时位于Generation 0中,当Generation 0的空间将被耗尽时,Mark Compact算法被启动。经过几次GC后如果这个对象仍然存活则会将其移动到Generation 1中。同理,如果经过几次GC后这对象还是存活的,则会被移动到Generation 2中,直到被移动到最高级中最后被回收或者是同程序一同死亡。 采用Generation的最大好处就在于每次GC不用对整个Heap都进行处理,而是每次处理一小块。对于Generation 0中的对象,因为它们死亡的可能性最大,所以对它们GC的次数可以安排多一些,而其它相对死亡的可能性小一些的对象所在的Generation可以少安排几次GC。这样做就使得GC的速度得到了一定程度的提高。这样就产生了几个有待讨论的问题,首先是应该设置几个Generation,每个Generation应该设置成多大,然后是对每个对象升级时它应该是已被GC了多少次而仍然存活。关于.net CLR对这个问题的处理,在本文的最后将给出一个例子对其进行测试。
using System;
namespace gcTest
{
class gcDemo
{
private static void GenerationDemo()
{
// Let's see how many generations the GCH supports (we know it's 2)
Console.WriteLine("Maximum GC generations: {0}", GC.MaxGeneration);
// Create a new BaseObj in the heap
GenObj obj = new GenObj("Generation");
// Since this object is newly created, it should be in generation 0
obj.DisplayGeneration(); // Displays 0
for(int i = ; i <= GC.MaxGeneration; i++)
{
// Performing a garbage collection promotes the object's generation
GC.Collect();
obj.DisplayGeneration(); // Displays i
}
obj = null; // Destroy the strong reference to this object
for(int i = ; i <= GC.MaxGeneration; i++)
{
GC.Collect(i);
GC.WaitForPendingFinalizers();
//suspend this thread until the freachable queue of
//the i generation has been emptied
//only when i = GC.MaxGeneration, this finalization method
//of obj will be performed
}
Console.WriteLine("Demo stop: Understanding Generations.");
//total gc times
//generation 0 : 5 times
//generation 1 : 4 times
//generation 2 : 3 times
}
public static void Main()
{
GenerationDemo();
}
}
class GenObj
{
private string objName;
public GenObj(string name)
{
this.objName = name;
}
public void DisplayGeneration()
{
Console.WriteLine("I am in Generation {0}", GC.GetGeneration(this));
}
};
}
这是个有趣的例子,首先利用GC.MaxGeneration()得知了在.net CLR中的GC采用了3代的结构,即Generation 0~2。接下来在Managed Heap上分配了一个GenObj的实例obj。在开始时obj位于Generation 0中,然后对整个Managed Heap进行两次GC。可以发现每进行一次GC存活的对象都会升一级直至到达Generation 2中。设置obj = null,这样做是为了取消root对obj的强引用,使obj成为垃圾。紧接着利用GC.Collect(i)对Managed Heap逐级进行GC,这个方法会对Generation 0~i进行GC。GC.WaitForPendingFinalizers()的作用是使整个进程挂起,等到Freachable Queue中所指向的对象的Finalize方法被调用。这样做的目的是为了保障对本次GC所确定的垃圾进行完全的回收,而不会因为对象的Finalize方法使对象复生。
二、using与new区别:
using两种用法;1.调用命名空间 2.声明一个生存区间,在区间之外,区间内声明的变量自动消亡,被回收,当对象使用了非托管资源或是比较宝贵的资源时使用;
new有两种用法:1.实例化一个对象 2.声明隐藏基类方法
三、托管资源与非托管资源:
最常见的一类非托管资源就是包装操作系统资源的对象,例如文件,窗口或网络连接,对于这类资源虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。还好.net Framework提供了Finalize()方法,它允许在垃圾回收器回收该类资源时,适当的清理非托管资源。如果在MSDN Library 中搜索Finalize将会发现很多类似的主题,这里列举几种常见的非托管资源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader ,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等资源。可能在使用的时候很多都没有注意到!
关于托管资源,就不用说了撒,像简单的int,string,float,DateTime等等,.net中超过80%的资源都是托管资源。
非托管资源如何释放,.NET Framework 提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。默认情况下,Finalize 方法不执行任何操作。默认情况下,Finalize 方法不执行任何操作。如果您要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写 Finalize 方法。然而大家都可以发现在实际的编程中根本无法override方法Finalize(),在C#中,可以通过析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用。
关于.net的一些基础知识(一)的更多相关文章
- .NET面试题系列[1] - .NET框架基础知识(1)
很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...
- RabbitMQ基础知识
RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- selenium自动化基础知识
什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- APP测试入门篇之APP基础知识(001)
前言 最近两月比较多的事情混杂在一起,静不下心来写点东西,月初想发表一遍接口测试的总结,或者APP测试相关的内容,一晃就月底了,总结提炼一时半会也整不完.放几个早年总结内部培训PPT出来 ...
随机推荐
- margin负值的使用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 设计的SOA架构
新来老大年前开会说各位同学,公司业务越来越重,未来几年要成倍增长......,要梳理出一套新架构,才能更好的支持N万用户.....,以后升职加薪当上....打败..... 想想还有点小激动呢,于是过年 ...
- [cc150] 括号问题
Implement an algorithm to print all valid ( properly opened and closed) combinations of n-pairs of p ...
- android 在Fragment里添加Theme主题
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanc ...
- maven 依赖排除
在项目中遇到一个问题,项目使用spring 3.x,引用了某些包,这些包又依赖了spring2.x,造成项目无法启动.这种情况就需要用到maven的依赖排除,配置如下: 使用以下代码排除依赖xxxx引 ...
- ANDROID_MARS学习笔记_S01原始版_008_Handler(异步消息处理机制)
一.流程 1.点击按钮,则代码会使handler把updateThread压到队列里去,从而执行updateThread的run() 2.run()里会通过msg.arg1 = i 和bundle来写 ...
- OpenSSL 与 SSL 数字证书概念贴
SSL/TLS 介绍见文章 SSL/TLS原理详解(http://seanlook.com/2015/01/07/tls-ssl). 如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自 ...
- Android开发UI之自定义控件的皮肤
定义一个button的皮肤,设置属性android:background="@drawable/button_skin",button_skin.xml文件为要下文中的资源文件. ...
- Oracle备忘录
习惯是一个数据库中有多个用户,但是一个用户对应一个系统 数据库管理员主要职责: 每个Oracle数据库应该至少有一个数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库 ...
- [Hadoop源码解读](五)MapReduce篇之Writable相关类
前面讲了InputFormat,就顺便讲一下Writable的东西吧,本来应当是放在HDFS中的. 当要在进程间传递对象或持久化对象的时候,就需要序列化对象成字节流,反之当要将接收到或从磁盘读取的字节 ...