GC浅谈

来源:互联网 发布:海德格尔 知乎 编辑:程序博客网 时间:2024/05/20 01:45

GC对一个java开发人员来说是个比较重要的东西,虽然在我们开发的过程中我们很少主动的调用它,但是它确实是我们开发中必不可少的部分.传说中的守护线程GC. 之前面试看过一些关于GC的面试题,感觉自己对GC的理解深入了一点,想写一些自己的体悟.
1.首先说GC就要说Java是如何储存对象的,我们说new一个对象,实际是给这个对象在内存中开一个内存区域,(这里说一下Java中new一个对象实际是完成了两步,即先实例化-开辟内存空间,在初始化-赋予一个初始值.
这个时候要说一下C和Java的储存清理机制了.我觉得这一块Think in Java中说的很棒的比喻: 在C中这就好像一个大院子,每个对象占据一个底盘,清理的时候,把死去的从他的地盘里清理掉就可以了,而在java中,这就好像一个传送带,创建一个对象就在等于像在传送带上放一个货物(堆),并且在旁边的清单上记录一下放的位置(栈),这样效率会很高,但是如果这个清单上的东西太长会严重影响到性能,而且在实际运行中也不会完全像传送带一样工作,可能会出现其他的问题,这个时候GC登场,清理’死了’的清单对象,缩短清单的长度,将堆空间重新排列,提高运行速度和清理出多余的空间.

2.GC回收实现的核心思想: 任何活着的对象,一定是可以追溯到存活在堆栈或者静态储存区的引用.即通过堆栈或者静态储存区的引用来判断这个对象是否还’活着’. 3.关于如何清理’死亡’的对象 其实有一个很low的方法,类似于数据库中的乐观锁机制,给所有的对象一个状态值,例如,状态值=1,是存活,状态值=0,是死亡,回收时,遍历每个对象的状态值就可以,这个方法很简单,很好理解,但是对性能的开销太大,low到爆炸. 最原始的两个GC处理方式是:

3 暂停清理.
顾名思义:停止所有线程的工作,先清理死亡对象,复制活着的对象, 打个比方来说,这就像在一个图书馆里有很多人在读书区坐着读书,这就相当于堆栈中活着的对象,同样桌上上还有很多没有做人的位置,但是却放着书,占着座位,这就相当于死掉的对象,现在有一个管理员负责把回收这些没人却放着书的座位上的书,它采用的方式是在傍边准备一个空白的看书区,让所有正在看书的人停下手上的工作,站起来,都坐到旁边他准备的没人的区域,当然大家要相连的坐在一起,做好后管理员把之前区域所有书籍收起来,并且对大家新的座位进行记录(这里是将新的引用地址记录到栈),这样有一个最大的问题,就是当这个图书馆基本稳定都是那些看书者来的时候,很少出现座位有书无人的情况,对性能的浪费有点大,这时SUN公司在java初始版本提供了另一个优化的处理方式,就是下面这个方法.

4 标记处理.
java加入了一套判断机制,还拿上面举的事例来说的话,就是管理员发现图书馆看书的人稳定后,自动切换到第二种模式,即标记处理,他在主动去巡逻看到某个座位有书无人时,放一个标记,当巡逻完成后,会从头清理掉标记座位的书,当然这还有一个问题,就是大家做的位置因为清理变得不连续,这个时候还是要集体停止下来,挪座位.

5 其他方式
上面提到的处理方式基本也是最原始的GC清理方式,虽然加入了优化,但是还有存在一定的性能问题,目前的GC算法基本还少见到这两种方式了.

未完待续….

原创粉丝点击