关于.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出来 ...
随机推荐
- 解决iphone safari上的圆角问题
-webkit-appearance : none ; /*解决iphone safari上的圆角问题*/
- 【Uva11212】 Editing a Book(IDA*)
[题意] 有n个数字的全排列,每次可以剪切一段粘贴到某个位置.问最后变成升序最少多少步. 如"{2,4,1,5,3,6}要2步 {3,4,5,1,2}只要一步 [分析] 迭代深搜真的AC了也 ...
- 李洪强iOS开发之-环信04_消息
李洪强iOS开发之-环信04_消息 消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage.EMMessage 由 EMMessageBody 组成. 构造消息 构造文字消息 EMT ...
- C++的表驱动法
目的:使用表驱动法,替换复杂的if/else和switch/case语句. 说明:JS 等其他语言也都支持的. 表驱动发示例:http://blog.csdn.net/zhouyulu/article ...
- 了解实时媒体的播放(RTP/RTCP 和 RTSP)
http://blog.csdn.net/span76/article/details/12913307 RTP/RTCP RTP是基于 UDP协议的, UDP不用建立连接,效率更高:但允许丢包, 这 ...
- 转载爱哥自定义View系列--文字详解
FontMetrics FontMetrics意为字体测量,这么一说大家是不是瞬间感受到了这玩意的重要性?那这东西有什么用呢?我们通过源码追踪进去可以看到FontMetrics其实是Paint的一个内 ...
- html5 高级动画精灵
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- Visual Studio中一个解决方案设置多个启动项目
在解决方案上右键,选择属性. 这样设置之后,点击开始运行之后,会同时启动2个项目. 适合一个项目既包含客户端也包含服务端,方便调试
- zoj 1033 与其说是搜索,不如说是枚举
zoj 与其说是搜索,不如说是枚举,只不过是通过搜索来实现的罢了. 主要是要注意好闰年的判断,特别是要注意好一串数字的划分. 题意其实我也看了一个晚上,才渐渐的看懂. 题意: 给你一个字符串,其中包含 ...
- 用PowerShell批量部署wsp包
转:http://www.xuebuyuan.com/168337.html 提供wsp部署的参数: $wsppath:wsp文件所在的路径,如"c:\" $wspnames:路径 ...