简明版 垃圾回收算法

本文是学习《深入理解JAVA虚拟机》的学习笔记(2)此篇是概念性东西,可结合下节的垃圾回收器一起看

Java是可以自动回收内存的,什么时候需要虚拟机调优呢?当垃圾回收成为系统达到更高并发的瓶颈时。

垃圾回收第一步要确认哪些对象可以回收。就是那些不能再被任何途径使用到的对象。怎么找到这些对象,这就谈到可达性分析法。引用计数法,由于循环引用的问题,主流虚拟机均没选用它,这里就不再论述。

可达性分析(Reachability Analysis)

基本算法思想是通过一系列的GC Roots 开始搜索,所走过的路径就是引用链(Reference Chain),当某个对象没有任何引用链连接,即认为此对象不可用,就是被回收的对象。
在这里插入图片描述
那啥是GC Roots呢,在JAVA语言中包括:

  1. 虚拟机栈中引用的对象
  2. 方法区中静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中引用的对象

回收方法区

方法区中 废弃常量与无用类也可回收。其中判定无用类的条件很苛刻,有兴趣的可自己研究。

垃圾回收算法

标记-清除算法(Mark-Sweep)

最基础的算法,其后的算法是在此思路上有针对的改进。简单说,就是先标志出所有需要回收的对象,再一次性回收所有被标记的对象。
在这里插入图片描述
不足有两个:一是效率不高,二是产生大量不连续的内存碎片。

复制算法(Copying)

解决回收效率问题。把可用内存一分为二,每次只使用其中一块,当这块内在满了,把它上面还存活的对象,复制到另一块。然后再把原来已使用过的那块内在空间一次性清理掉。
在这里插入图片描述
优点:可以不用考虑内在碎片问题,复制时只要移动堆顶指针,按顺序分配内在就行了,简单高效。
缺点:是只使用一半的内存,浪费。

现在商用虚拟机采用这种算法时,改进了,不是按1:1来分。而是将内存分为一块较大的Eden空间和两块较小的Survivor空间。每次使用Eden和其中一块Survivor,回收时,先将这两块中存活对象复制到另一块Survivor上,然后一次性清理这两块。HotSpot中默认Eden和两个Survivor的比例是 8:1:1。内存利用率就从50%提高到90%。
在这里插入图片描述
这里涉及一个问题,回收时,Eden和Survivor上存活对象,在另个Survivor上放不下时,会引出分配担保(Handle Promotion)这个问题,随后再细说。不用担心放不下,人家可以借用别的地方的内存

标记整理算法(Mark-Compact)在这里插入图片描述
与“标记-清除”算法一样,也是先进行标记,之后与其不同,是让所有存活的对象向一端移动,然后直接清理掉边界以外的内存。

分代收集算法(Generational Collection)

根据对象存活周期不同而将内存划分为几块,一般把JAVA堆分为新生代和老年代,根据各个代不同的特点,采用适当的收集算法。在新生代中,垃圾收集时都会发现有大批对象死去,只有少量存活,那就选用复制算法,将存活的对象复制就可以完成回收。而老年代对象存活率高、没有额外的空间对它时行分配担保,必须使用“标记-清除”或“标记-整理”算法来进行回收。相关详细内容,之后系列文章会详细介绍

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值