1.垃圾收集器(GC)控制着托管内存。但是我们需要对非托管代码进行处理(数据库连接,文件句柄,GDI+对象,COM对象等)

 

2.垃圾收集器是运行在一个单独的线程中来移除程序中不再使用的内存。并且还会压缩托管堆,使得空闲内存能集中在一个连续的区域。

 

3.对于非托管资源我们需要在类型中定义一个终结器,以此来确保释放这些系统资源。在对象的内存被回收之前,系统会调用终结器,这样我们可以在终结器中编写我们的代码来释放该对象占有的非托管资源。值得注意的是对象的终结器是在对象成为垃圾之后调用的,但是在内存归还之前,但是我们无法精确的控制“不再使用对象”和“执行终结器”这2个事件之间的关系。

 

4.当GC发现某个对象是垃圾但是需要终结器时,它还不能直接从内存上删除这个对象。首先,它要调用终结器,但终结器的调用不是在垃圾回收器的同一个线程上运行的。取而代之的是,GC不得不把对象放置到终结器队列中,让另一个线程让执行所有的终结器。GC继续它自己的工作,从内存上移除其它的垃圾。在下一个GC回收时,那些被终结器了的对象才会再从内存上移除。

 

5.Net回收器定义了一种称为“代龄”的机制来优化。代可以帮助GC来很快的标识那些看上去看是垃圾的对象。所有从上一次GC回收后开始创建的对象称为第0代对象,所有那些经过一次GC回收后还存在的对象称为第1代对象。所有那些经过2次或者2次以上GC回收后还存在的对象称为第2代对象。代龄的目的就是用来区分临时变量以及一些应用程序的全局变量。第0代对象绝大部分是临时的变量。成员变量,以及一些全局变量很快会成为第1代对象,最终成为第2代对象。GC通过限制检测第1以及第2代对象的频度来优化它的工作。每一次GC循环都检测第0代对象,大概10次GC周期才会检查第0和第一代对象,大概100次GC周期才检查一次第0,1,2代对象。让我们考虑一下:一个须要终结器的对象可能要比一个不用终结器的对象在内存里多待上9个GC回收循环。如果它还没有终结器,它将会移到第2代对象。在第2代对象中,一个可以生存上100个GC循环直到下一个第2代集合。

 

6.记得一个垃圾回收器负责内存管理的托管环境的最大好处:内存泄漏,其它指针的相关的问题将不再存在。非内存资源迫使你要使用终结器来确保清理非内存资源。终结器会对你的应用程序性能产生一些影响,但你必须使用它们来防止资源泄漏。通过实现IDisposable接口并且使用它可以避免终结器在垃圾回收器上造成的性能损失。

 

 

 

posted @ 2011-01-05 00:05 yu_liantao 阅读(73) 评论(0) 编辑

本内容参考大话设计模式记录

对象:一切事物皆对象。:对对象进行的抽象。实例:类的一个具体实体。

方法重载:方法名相同但是参数类型或者个数不同的方法。

面向对象的三大特性:继承,封装,多态

继承:子类继承父类后具有父类的保护和公有的一些方法,属性等并且能扩充自己。对于父类的构造函数只能调用不能继承。当对象与对象的关系是is-a时候用继承,当关系式has-a我们应该用组合或者聚合(桥接模式)。

封装:一个类在其内部拥有自己的方法,字段完成一些操作而不需要其他类,内部变化对于外面是不清楚的,只是提供一个接口。

多态:子代父完成一些操作(用到Virtual和Override),也就是依赖倒置原则的核心。(也就是调用的父类的方法,但是执行的是子类的函数实体),但是有个缺点就是,子类的扩展不能使用。

重构:对现有代码优化,把重复出现的部分抽取出来。(模板方法模式,提取抽象类等方法)

抽象类:对类的抽象。(类是对对象的抽象,接口是对方法的抽象,代理也是对方法的抽象),当我们发现我们创建的类不需要去实例化的时候我们可以把它设计为抽象类,注意的是抽象类必须被子类重写的,抽象类尽可能的拥有多的共同代码,尽量少的数据。

接口:把一些特定的方法或者属性进行抽象。

接口和抽象类的区别:一个类可以继承多个接口,但只能继承一个抽象类。抽象类可以给出一些成员的实现,而接口不能。抽象类的抽象成员可以被子类部分实现,而接口需要完全实现。抽象类是对对象的整体抽象,接口是对对象的局部抽象(方法和属性)。对于行为跨越不同的类对象的时候我们应该用接口,对于一些相似的对象我们用抽象类。从设计的角度分析,抽象类是从子类中发现公共的部分,泛化出父类,然后子类继承父类。而接口是根本就不知道子类的存在,方法如何实现还不确定,预先定义。(抽象是自底而上,接口是自顶而下)。

集合数组(分配空间固定,易于读取,不利于更改)。ArrayList易于更改,可以添加不同类型的数据(导致它是不安全类型),但是对于数据的操作的时候大量用到了装箱和拆箱的操作,占用了大量的空间和时间。注意:它的一个操作将带动所有的其他成员发生变化。比如我们要连续删除前2个成员要用:ArrayList.Remove(0);ArrayList.Remove(0);而不是ArrayList.Remove(0);ArrayList.Remove(1);

泛型:为了解决ArrayList的装箱和拆箱带来性能上的问题。(我觉得泛型就是通过参数预先给不同的数据先制定需要存储一个单位的空间),用IList<T> Lists=new List<T>解决。它的好处在于解决了类型安全和装箱拆箱操作。

事件与委托:委托是函数的封装或者说是函数的另外一种表现形式。而事件则是委托的一种特殊形式,委托是一种引用方法的类型,一旦委托分类方法成功,那么委托和方法具有相同的行为。而事件是说在发生其它类或对象关注的事情时,类或对象可以通过事件通知他们。

下面代码展示怎样在类中建立委托,事件,并且在实例后怎样给事件赋值(事件的触发是类内部触发的,外部只需要给事件赋值就行了,一般在内部触发先要判断事件是否为空,然后调用)

 

namespace 动物练习
{
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat("Tom");
            Mouse mouse1 = new Mouse("Jerry");
            Mouse mouse2 = new Mouse("Jack");
            cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
            cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);

            cat.Shout();

            Console.Read();
        }
    }

    //无参数委托事件
    class Cat
    {
        private string name;
        public Cat(string name)
        {
            this.name = name;
        }

        public delegate void CatShoutEventHandler();
        public event CatShoutEventHandler CatShout;

        public void Shout()
        {
            Console.WriteLine("喵,我是{0}.", name);

            if (CatShout != null)
            {
                CatShout();
            }
        }
    }

    class Mouse
    {
        private string name;
        public Mouse(string name)
        {
            this.name = name;
        }

        public void Run()
        {
            Console.WriteLine("老猫来了,{0}快跑!", name);
        }
    }

带参数的事件

 

namespace 动物练习
{
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat("Tom");
            Mouse mouse1 = new Mouse("Jerry");
            Mouse mouse2 = new Mouse("Jack");
            cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
            cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);

            cat.Shout();

            Console.Read();
        }
    }

 

    //有参数委托事件
    class Cat
    {
        private string name;
        public Cat(string name)
        {
            this.name = name;
        }

        public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);
        public event CatShoutEventHandler CatShout;

        public void Shout()
        {
            Console.WriteLine("喵,我是{0}.", name);

            if (CatShout != null)
            {
                CatShoutEventArgs e = new CatShoutEventArgs();
                e.Name = this.name;
                CatShout(this, e);
            }
        }
    }

    public class CatShoutEventArgs : EventArgs
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    class Mouse
    {
        private string name;
        public Mouse(string name)
        {
            this.name = name;
        }

        public void Run(object sender, CatShoutEventArgs args)
        {
            Console.WriteLine("老猫{0}来了,{1}快跑!", args.Name, name);
        }
    }
}

 

posted @ 2010-12-04 17:07 yu_liantao 阅读(78) 评论(0) 编辑

1.对于SQL2000和SQL2005实用的分页

方法一:

SELECT TOP 页大小 *
FROM table1
WHERE id NOT IN
          (
          
SELECT TOP 页大小*(-1) id FROM table1 ORDER BY id
          )
ORDER BY id

方法二:

SELECT TOP 页大小 *
FROM table1
WHERE id >
          (
          
SELECT ISNULL(MAX(id),0
          FROM 
                (
               
SELECT TOP 页大小*(-1) id FROM table1 ORDER BY id
                ) 
A
          )
ORDER BY id

 

2.实用与SQL2005

注解:这个方法不适合用于大量数据后面的分页

SELECT TOP 页大小 * 
FROM 
        (
        
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
        ) A
WHERE RowNumber > 页大小*(页数-1)

 

解决办法(参考别人的博客)

  select * from table1 where id in (
select id from 
(
select id, row_number() over (order by id)
 scn 
from   table1) t
where scn<100000 and scn>100000-20)

这样就能取出99980到100000之间的数据,依靠id具有的索引读取出来就很快

 

 

 

posted @ 2010-10-06 13:32 yu_liantao 阅读(226) 评论(0) 编辑

1.获取记录总数的优化  

select rows from sysindexes where id = object_id('tablename') and indid in (0,1)

sysindexes 系统表中拥有至少一条其他表的记录,其中rows记录总数,object_id('tablename')表示转换成表对应在sysindexes 的id编号, indid 表示是具体的对象,当表没有聚簇索引时,Indid = 0 否则为 1,这比count快的多

posted @ 2010-09-29 23:21 yu_liantao 阅读(229) 评论(0) 编辑