个人读书笔记---“深入理解java虚拟机”---垃圾回收

来源:互联网 发布:使命召唤ol流畅优化 编辑:程序博客网 时间:2024/05/21 04:20

一、判断对象是否“已死”

两种方法,一种为“引用计数法”,一种为“可达性分析算法”

引用计数法

给对象添加一个引用计数器,当有一个地方引用他时,计数加1,引用失效,计数减1,当计数为0时,该对象“已死”

用于:com技术,flashplayer,python。

缺点:难以解决对象间相互引用的问题,不作为主流的算法

可达性分析算法

从一个GC root出发,向下搜索可达的对象引用,所有在引用链上的对象不用回收。主流的算法

GC root:虚拟机栈中引用的对象;方法区中静态属性引用的对象;方法区中常量引用的对象;本地方法栈中引用的对象(此条不明确,我理解的类似于object类的对象??)


二、垃圾收集的算法

1.标记--清除

标记阶段,将所有课回收的对象标记,清除阶段将这些对象统一回收。简单

缺点:耗时长,清理后的碎片较多。

2.复制

将内存分为两个区域,一次只使用其中一块内存,当其中一个区域已满,将该区域的活着的对象复制到另一块,然后将这块区域全部回收。

缺点,可利用内存空间减少,复制时可能会延长GC的时间

因为主要用于新生代,所以改进为将内存分为3部分,一部分为survivor,剩下为相等大小的Eden区,survivor与Eden的比为8:1,这样能比较好的利用内存空间

3.标记--整理

同样先标记要回收的对象,然后将存活且不需要回收的对象向一段移动,然后清除边界值之外的对象

缺点:虽然书上没有写,但是我觉得当活跃对象众多且零散的情况下,将这些对象整理可能耗时较长。

4.分代收集

简单来说就是根据不同情况使用不同算法,若将堆分为新生代与老年代,那么适合新生代的算法为复制算法,对于老年代采用标记整理算法比较适合


三、垃圾收集器

新生代:Serial,ParNew,Parallel Scavenge

Serial:单线程收集器,一般用于client模式

ParNew:Serial的多线程版,并行运行,一般用于server端,可与CMS搭配使用

Parallel Scavenge:多线程,并行运行,注重吞吐量,通过设定吞吐量,优化GC性能





老年代:CMS,Serial Old,Parallel Old

Serial Old与Parallel Old只是新生代的老年版

CMS:采用标记--清除算法而不是标记--整理,能够实现最短停顿时间。分4个阶段标记清除,初始标记--并发标记--重新标记--并发清除。初始标记阶段标记GC roots可以直接关联到的对象,并发标记是与用户线程并发,在此期间通过GC roots tracing对象。重新标记是标记在并发过程中标记对象变动的记录。最后与用户线程并发清除。其中初始标记与重新标记也是需要“stop the world” ;缺点有三:对CPU资源敏感,无法处理浮动垃圾,由于基于标记清除算法,会产生大量碎片。

G1:没有明确的新生代与老年代的区别,类似于CMS,但不同于CMS的是划分多个大小相同的region,每个region会评估价值,回收价值高的会优先回收。分四个阶段:初始标记--并发标记--最终标记--筛选回收,类似于CMS四个阶段,不同的是筛选回收的时候并不是并发的。












阅读全文
0 0
原创粉丝点击