详解JVM垃圾收集算法

1. 标记—清除算法(Mark-Sweep)

标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象这里写图片描述
该算法有两个不足:
一是效率,标记和清除两个阶段效率都不高。
二是空间问题,标记清除后会产生大量不连续的内存碎片,这样以后在位大对象分配空间时,由于找不到足够的连续内存会提前出发下一次GC。

2. 标记—整理算法(Mark—Compact)

标记-整理算法适合用于存活对象较多的场合,如老年代。它在标记-清除算法的基础上做了一些优化。
和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象移动到内存的一端。之后,清理边界外所有的空间。
这里写图片描述

3. 复制算法(Copying)

与标记-清除算法相比,复制算法是一种相对高效的回收方法。
不适用于存活对象较多的场合,如老年代。
将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。
这里写图片描述
JavaGC、新生代、老年代
Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
在Java中,堆被划分成两个不同的区域:新生代(Young)、老年代(Old)。新生代(Young)又被划分为
三个区域:Eden、From Survivor、To Survivor。
这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包括内存的分配以及回收。
这里写图片描述
从图中可以看出:堆大小=新生代+老年代。其中,堆的大小可以通过参数–Xms、-Xmx来指定。
默认的,新生代(Young)与老年代(Old)的比例的值为1:2(该值可以通过参数–XX:NewRatio来指定,即:新生代(Young)=1/3的堆空间大小。老年代(Old)=2/3的堆空间大小。其中,新生代(Young)被细分为Eden和两个Survivor区域,这两个Survivor区域分别被命名为from和to,以示区分。
默认的,Eden:from:to=8:1:1(可以通过参数–XX:SurvivorRatio来设定),即:Eden=8/10的新生代空间大小,from=to=1/10的新生代空间大小。
JVM每次只会使用Eden和其中的一块Survivor区域来为对象服务,所以无论什么时候,总是有一块Survivor区域是空闲着的。因此,新生代实际可用的内存空间为9/10(即90%)的新生代空间。
这里写图片描述

4. 分代收集算法(Generational Colletion)

依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代。主流虚拟机采用这种算法。
根据不同代的特点,选取合适的收集算法。
少量对象存活,适合复制算法
大量对象存活,适合标记清理或者标记整理算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值