我眼中的爱情----浅谈垃圾回收(转)

    十一坐车回沈阳,突然之间好想她,从来没有过的思念。虽然只是短短的四个小时不见,却是恍若隔世。头疼,心痛,从来没有过的感受充满了我的身体。
    其实,我早就知道,我很爱她,我是那么爱她。虽然我和她从第一次见面至今才只有短短地半个月。我不爱去承认,也不敢去承认。因为,我知道,她是有男朋友的,她对我来说是那么遥远,我对她来说只不过是个朋友罢了,甚至连朋友都算不上。

    于是,我便开始想,究竟什么是爱情?是啊,究竟什么是爱情呢?究竟怎么解释我对她的这份感情呢?
头晕晕的,迷迷糊糊之间,我给爱情下了一个这样一个定义:爱是对彼此双方的习惯性依赖。我对自己笑了笑,这个概念听起来还蛮有几分哲理。
    可是突然,我感觉这个定义好熟悉,依赖,这个词实在太习惯见到了,这时,我想到了对象,呵呵。首先,我来分析下对象的本质。C#是门面向对象的语言,世间万物皆是对象,对象是类的具体表现形式。其实对象是怎么样在计算机中体现的呢?其实,对象就是托管堆上的一块内存地址,然后有一个引用指向了这块内存。这个观点匆匆从我脑中划过,我继续想着这段让我困惑的爱情。爱情是对彼此双方的习惯性依赖。那么所谓的日久生情就是指时间长了,自然对彼此的存在产生了习惯,于是就产生了感情。而时间和空间将一段感情渐渐地淡化,其实也就是习惯了对方的不存在,那么习惯自然也就渐渐地淡化了。想到了这些,开始有些明白了,她住在我们的房子,每天晚上都能看到她,渐渐地,看到她,她的音容笑貌,她的一颦一动,其实早已深深印在了我的脑中,成为了一种习惯,成为了我生活中的一部分,不能缺少。
    这个时候恍然大悟,我说怎么觉得爱情如此熟悉,原来这个爱情的道理,其实正是垃圾回收的本质原理!让我们来看下垃圾回收的机制。
    在.NET中,垃圾回收采用的是代机制。先看例子,
Class Love
{
Public Love(string boyName,string girlName){……}
.
}

    然后构造一个Love的对象,Love truelove=new Love(“Huangxin”,”WK”);
    让我们来看下这个爱的发展过程。由于刚刚认识,感情肯定会很浅,其实这就对应着垃圾回收的第0代对象,0代对象其实就是刚刚构造的对象,很容易回收,回收效率很高。然后认识了一段时间,感情逐渐变深,这对应着垃圾回收中的第1代对象,第1代对象是0代对象经过一次回收后,剩余未被回收的对象,这一代对象较之第0代对象不易被回收,而且回收效率也较低。认识了很长一段时间后,感情越来越深,变成生活中不可缺少的一部分。这对应着垃圾回收中的第二代对象,这代对象基本不会被垃圾回收器GC回收,而且即使回收了回收效率也会很低。(也许说到这里,大家还是以头雾水,别着急,继续向下看)
    想到了这里,我开始找爱情和垃圾回收的共同点。总结归纳如下:
         
         1.我不相信一见钟情,正如对象不会一经创建就立即成为第二代对象。   

    成文当天,我收到了一条短信,上面有一句这样的话,不要相信一见钟情,因为你不可能第一眼就看出这个人是否有钱。其实这个有些玩笑的意思,但是我是不相信一见钟情的。爱是全方位的,所谓的一见钟情,看中的只是对方的外形罢了,当有一天鲜花凋谢,你还会像从前一样爱她么?当有一天,她已经属于了你,你也渐渐地审美疲劳,你还会再爱她么?
  垃圾回收也是一样,让我们来分析一下垃圾回收的过程。前面说过,.NET的垃圾回收采用的是代机制,.NET中,把对象的代数分为3代,也就是第0代,第1代,第2代,CLR为每一代对象都分配一定的内存,一般来说是第0512K,第一代2M,第二代8M。只有当某一代的空间被充满时,才会引发垃圾回收器对这一代的内存空间进行垃圾回收。比如说我们构造了10000Love对象,分别为Love1,Love2,Love3……,首先被填充的肯定是第0代对象的512K空间被充满,然后垃圾回收器便对第0代对象所在的内存空间进行垃圾回收,这个时候发现Love0,Love2,Love4,Love6…...是没有引用指向的,也就说他们其实已经成为垃圾。于是垃圾回收器便将他们回收,而讲Love1,Love3,Love5……列入了第1代对象。我们想这个过程,随着垃圾回收的不断进行,有越来越多的对象成为了1代对象,总会有那么一刻,第一代对象的2M空间也被填满了,这个时候,垃圾回收器就会找出第一代对象中的垃圾进行回收,而将仍有引用指向的对象置为第二代对象。不知道大家明白了么?
  所以说,一个对象成为难以被回收的第二代对象,是需要不断地经过垃圾回收器的考验和证明的,而不存在这样一个对象,一经创建便马上成为第二代对象。
   

    2.也许会有这么一段爱情迅速地占据了你的心,那只是因为这个对象是个大对象
   也许没有一见钟情,但是真的会有很快的感情。我过去从来都不相信,但是这次我不得不信。其实,爱情是个很让人为难的东西,他很多时候需要一种博弈。其中最常见的就是游鸿明的一首歌《爱我的人和我爱的人》,爱我的人对我执着无悔,我却为我爱的人慌乱心碎。爱我的人为我付出无数,而我心中却总是念着那个我爱的人。爱我的人和我在一起一年多,我却没有办法培养出一点点感情,而那个女孩只需要半个月,就可以让我日思夜想,这也许就是爱情吧。
    老师上课讲,引用对象都是存储在托管堆上,这句话是不全面的。其实,存储对象有两种数据结构,分别为老师讲的托管堆,另外就是LOH(Large of heap),也成为大对象存储堆。当一个对象足够大的时候,CLR考虑到效率问题(主要是对象的创建效率问题),便会将他放到LOH中,这段地址比第二代对象还不容易被回收,而且效率更低。
    其实,感情也是一样,当你遇到一份这样的爱情时,这份感情真的让你无法忘记,哪怕知道最后什么都得不到,正如天龙八部中,段誉对神仙姐姐的那份痴情。

    3.时间越久,忘记越难。正如代数越大,回收效率越低,越难被回收。
    十一我回到沈阳,其中很大的因素就是因为我希望我可以冷静下来好好考虑考虑。这些天的相处,我早已经养成了这样的生活习惯,每天坐在客厅,然后等着她出她的屋门,好好地看她一眼,然后和她打上一声招呼。每天,我最大的动力就是快点过去白天,然后晚上回去可以看到她。面对这份不现实的感情,我前所未有的迷茫,也是前所未有的不理智。我不在乎她有没有男朋友,不在乎我所做的一切究竟可以带来什么!我只是希望她幸福,只是希望她能够每天都能够快快乐乐的,没有一点不开心。但是我懂,我不能让自己越陷越深,这份感情我只能深埋在心底,而不应该有半点外流,让她觉得我只是拿她做朋友。时间越久,陷得越深,忘记越难。
    前面说过,垃圾回收采用的是代机制。但是为什么代数越高,回收越难呢?这就涉及到了垃圾回收的另外一个知识点——垃圾回收时究竟如何判断垃圾。
    在这里声明一点,我们抛去了实现
Finalize方法的类对象不谈.
    在.NET中,每一个可用的对象,就是说在之后的代码中还仍然要被使用的对象都有着一个指向他的引用。在垃圾回收开始时,垃圾回收器要遍历所要回收代数的内存地址中的所有对象,查找是否存在指向该对象的引用。如果存在,那么便将这个对象放到一个可达对象图(如果不懂,可以补下数据结构的知识了)中,最后也就是生成了一个大的可达对象图,图上的每个节点其实都是可达的对象(不是垃圾),然后垃圾回收器变将不再图中的对象回收,最后将可达对象图中的对象升级为上一代对象。
这里我们注意到,垃圾回收器是遍历所回收代数的所有对象。好了!效率的高低问题就出在这,由于代数越高,所占有的内存空间越大,那么遍历所有对象也就越困难,当然效率就会降低。另外,由于内存空间越大,想把这块内存空间填满就越难,如果不填满自然就不会进行垃圾回收。以上两点,得出结论,代数越高,回收效率越难,正如感情越久,忘记越难。


 

     4.爱情没有绝对的天长地久,正如托管堆空间有限。

 

 

     

 

 

     山无棱,天地合,乃敢与君绝,如琼瑶奶奶般对爱情有着如此追求的人尚且要对爱情做个期限,更何况吾等乎!无数的情侣最长说的一句话,我会永远爱你!可是又有着这样一首歌,叫《永远到底有多远》,是啊。永远是多远呢?我不再像曾经那样幼稚,一句句永远。对我爱着的这个女孩,我在心里偷偷向你表白,我爱你,这一生。只要能看到你,只要能见你幸福,只要能见你的笑,只要能听到你的声音,我此生足矣!

 

 

其实,.NET对内存空间做了很大优化,单单从代码执行效率以及内存分配空间来说,远远要优于C语言,但是为什么效率却仍然低于C呢。原因就在于.NET做了这样一个理想的状况,就是内存无限。但是不幸的是,这点是不可能的,托管堆的内存空间是有限的,这样就必然会引起垃圾回收,而.NET,甚至JAVA,与C语言相比,输就输在了垃圾回收上。

 


 

     5.如果使爱情长时间保鲜,而又如何使一个对象长时间不被回收呢?

 

 

     <1>使爱情长久,要做到两点:

 

 

     第一,这个感情本质上真的是爱。这个很容易理解,如果根本就没有爱,那又从何谈起是爱情保鲜呢?

 

 

     第二,心中时时刻刻想着对方,心中彼此挂念,衣食冷暖,大事小事,第一个想到的永远是那个你爱的人。

 

 

     <2>使对象长久,同样是两点。

 

 

     第一,这个对象必须要有强引用指向。(我稍后来解释)

 

 

     第二,一直有引用指向。也就是说你必须一直要有程序代码去使用这个对象。这样,这个对象不可能成为垃圾。

 

 

     好了,说下什么是强引用。其实,我们一直用的都是强引用。在这里,我就讲他的对立面,在.NET中,有这样一个概念是弱引用,WeakReference.什么是弱引用呢?就是说有引用指向,但是却允许垃圾回收。满足下列条件,我们就需要考虑使用弱引用了:

 

 

     1.创建了一个对象,但是不确定这个对象之后是否会被使用

 

 

     2.如果需要的话,这个对象可以被重新构造出来

 

 

     3.这个对象是个大对象,构建需要很长时间。

 

 

     举个WeakReference的例子,大家简单的了解下他的用法:

 

 

Love trueLove=new Love();

 

 

WeakReference wr=new WeakReference(trueLove);

 

 

if(wr!=null){.......}

 

 

else{trueLove=new Love();}

 

 

     好了,大概明白下就好,具体可以参考MSDN。

 

 

     不要妄图用什么来锁住明明不是爱情的感情。很多女孩为了锁住那个爱的人,不惜献出自己宝贵的第一次,希望这可以让他爱上他,千万不要这样,即使你这样做了,指向他的病不是你的真人,而只是一个弱引用罢了。一旦他遇到别人,他便会对你进行垃圾回收。那时,你真的就一无所有了。

 


 

     6.有的人会渐渐地占据你的心头,是因为垃圾回收的压缩算法

 


 

     也许你有的时候会同时对几个女孩产生好感,但你记得,那不是爱情,只是好感罢了。如果选择?最好的办法,就是等待时间的宣判,总会有人占据你的心头。成为你真爱的人!

 

 

     垃圾回收机制中有个很重要的概念,叫做压缩算法。具体微软是如何来实现的,我们无从得知。我们只需要知道,微软在进行垃圾回收的同时,对内存中剩余的对象进行了内存整理,把一些零散的对象放到了一起,放到了一块连续的内存上。

 

 

     也许你的心中有很多人,但是经过垃圾回收,最后只会剩下很少的对象,而垃圾回收器不会让她们零散地放在你心中不同的角落,而是会把他们整理到一起,终有一个对象占据着你心头的那个位置!

 


 

      这就是我所理解的爱情,顺便也提了一些简单的垃圾回收机制。其实世间万物都是想通的,在我们乱想的时候,我们不妨也想想,你想的那点对应着.NET的什么知识点,然后一一对应,慢慢地你会发现,世间万物,皆为NET。嘿嘿。

 

 

      好了,很晚了,该睡了。在这里,我知道那个女孩不可能进到这个地方。所以才敢大胆地写下这些.WK,其实你知道么?这么久,我好爱你。我永不会离去,我的爱像天使守护你。如果生命就到这里,我会找个天使替我一辈子爱你!你一定要幸福!

 

 

posted @ 2008-10-04 01:56  威尼斯的夏天  阅读(218)  评论(0编辑  收藏  举报