码迷,mamicode.com
首页 > 其他好文 > 详细

垃圾收集器与内存分配策略

时间:2015-05-09 16:39:59      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

此文内容摘自<深入理解java虚拟机 第二版>,选择一些脉络性的记录下,自己的理解很少,有时间看看还是可以的。


1.对象已死吗?

在堆里存放这java世界几乎所有的对象实例,垃圾回收器在对堆进行回收前,第一件事就是要确定这些对象之中那些对象还“存活”着,

哪些对象已经“死去”(即不可能再被任何途径使用的对象)。


1.1 引用计数器法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时就减1;任何计数器为0的对象就是不可能再被使用的。

引用计数器法实现简单,判断效率高,在大部分情况下是不错的算法。但是在主流的java虚拟机里面没有选用引用计数器法来管理内存,主要的

原因是它很难解决对象之间的相互循环引用的问题。如这种代码:

objA.instance = objB;

objB.instance = objA;

objA = null;

objB = null;

System.gc();//假如在这里发生gc,objA和objB实际上并没有回收。


1.2 可达性分析算法

算法的基本思路是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots

没有任何引用链相连时(从GC Roots到这个对象不可达),则证明此对象是不可用的。

在java语言中,可以作为GC Roots的对象包括以下几种:

(1) 虚拟机栈(栈帧中的本地变量表)中引用到的对象;

(2) 方法区中类静态变量引用到的对象;

(3) 方法去中常量引用到的对象;

(4) 本地方法栈中JNI (即一般所说的Native方法) 引用到的对象。

如下图所示,object5、object6、object7虽然有关联,但是它们到GC Roots是不可达的,会被判定为可回收对象。

技术分享

1.3 引用

在JDK1.2之前,java中的引用很传统:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。

一个对象在这种定义下只有引用或者没有没引用两种状态。

在JDK1.2之后,java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用 4种


2 垃圾收集算法

2.1 标记 - 清除算法

最基础的收集算法是 标记 - 清除 算法算法分为 标记 和清除两个阶段:首先标记出所有需要被回收的对象,在标记完成后统一回收所有被标记的对象。

不足:一个是效率问题,标记和清除两个过程效率都不高;另一个是空间问题,标记清除后产生大量的不连续的内存碎片,空间碎片太多可能导致以后

在需要分配较大对象时,无法找到足够的了连续内存而不得不提前触发另一次垃圾回收动作。

下图是 标记 - 清除 算法的执行过程图:图中上半部分是回收前状态,下半部分是回收后状态。

(下面这三张图都是直接拍的相片)

技术分享

2.2 复制算法

接了解决效率问题,一种称为“f复制”的算法出现了,它将可用内存分为大小相等的两块,每次只是用其中一块。当着一块的内存用完了,就将还存活的

对象复制到另一块上面,然后把使用过的内存一次清理掉。这样每次都是对整个半区进行内存回收,内存分配时不用考虑内存碎片等复杂情况,只要一动栈顶指针,

按顺序分配内存即可,实现简单,运行高效。

不足:将内存缩小为原来的一般,代价有点高。

下图是复制算法示意图:(此图中 存活对象 和保留区域 颜色基本一样,自己区分)

技术分享

2.3 标记 - 整理算法

根据老年代的特点(对象存活率比较高),有人提出了另外一种 “标记 - 整理” 算法,标记过程任然与“标记 - 清除” 算法一样,但后续步骤不是直接对可回收对象

进行清理,而是让所有的存活对象都向一端移动,然后直接清理掉端边界以外的内存.

下图是标记-整理算法示意图:

技术分享


2.4 分代收集算法

当前的商业虚拟机的垃圾收集器都采用 “分代收集” 算法,这种算法并没有什么新的思路,只是根据对象存活周期的不同将内存划分为几块。

一般把java堆分为新生代和老年代,这样就可以根据各个年代放入特点采用 适当的收集算法。在新生代垃圾收集时每次都发现有大批对象死去,

只有少量存活,那就选用复制算法,只要付出少量存活的对象的 复制成本就可已完成收集。而老年代中对象存活率比较高,

没有额外的空间对他进行分配担保,就必须使用“标记 - 清理” 或者 “标记 - 整理” 算法来进行回收。


3 HotSopt的算法实现

3.1 枚举根节点

3.2 安全点

3.3 安全区域


4 垃圾收集器

4.1




垃圾收集器与内存分配策略

标签:

原文地址:http://blog.csdn.net/wufengui1315/article/details/45489115

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!