java学习笔记-垃圾回收-垃圾回收相关算法

目录

标记阶段

引用计数算法

可达性分析算法(或根搜索算法、追踪行垃圾收集)

对象的finalization

JProfiler的GC Roots溯源

清除阶段(下面这些算法都会STW)

概述

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

复制(Copying)算法

标记-压缩(或标记-整理、Mark-Compact)算法

分代收集算法(前面算法结合)

增量收集算法、分区算法


标记阶段

  • 注意:标记阶段标记的非垃圾对象!

引用计数算法

  • JVM不采用这种算法
  • 引用计数算法就是用一个整型属性存储被引用的情况,比如有3个引用,那就是3
  • 引用计数算法无法处理循环引用
  • 引用计数算法需要单独字段存储计数器 增加了存储空间的开销
  • 引用计算算法每次赋值都需要更新计数器,伴随着加法和减法操作,增加了时间开销
  • 优点:实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。

  • 下面这种就是循环引用,如果采用引用计数算法,那当p置为null的时候,下面这三个对象就无法回收,因为始终有对象引用,导致内存泄漏

  • 验证JVM是否使用的是引用计数算法,结果明显是不是的,因为发生了GC回收

  • 小结

可达性分析算法(或根搜索算法、追踪行垃圾收集)

  • 可达性分析算法就是用个GC Roots集合引用链,枚举这个集合,判断某个对象是否还能被链到,能链到就不能回收,不能链到就回收,关于什么能作为GC Root下面会说

  • 什么能作为GC Roots

  • 小技巧:一个指针指向了堆里面的对象,这个指针又不在堆中,那就是一个Root(静态变量可以算是一个特殊,即使在堆中,也是Root)。

  • 注意:

对象的finalization

  • 机制

  • 虚拟机对象的三种状态 ,如果已经没有引用链了,调用finalize是有可能复活的,因为对象有三种状态;
  • 没调用过finalize方法时,对象还会有一个缓刑阶段,能够调用finalize(每个对象只能调用一次)的状态,通常称为可复活状态;
  • 调用过finalize方法后,如果对象又进入了缓刑阶段,就直接回收,因为finalize方法只能调用一次

  • 具体过程

JProfiler的GC Roots溯源

  • 用-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError 设置堆空间大小8m以及堆空间内存溢出后生成一个dump文件,在项目目录下

 

  • 直接双击用JProfiler打开就能看到是哪个大对象溢出了

清除阶段(下面这些算法都会STW)

概述

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

  • 标记阶段标记的是非垃圾对象,没被标记的才是垃圾对象;标记阶段是递归遍历GC Roots,时间复杂度也是近似O(n)了
  • 清除就是把堆遍历一遍,发现没被标记就回收,回收也不是真的回收,就跟电脑磁盘一样,格式化并没有真的删除,只是把地址回收了,下次往里面存东西就把原有的数据覆盖这样。
  • 综上:清除时时间复杂度O(n),效率并不是很高;这是缺点1,缺点2、3见下面图

  • 清除出来的内存不连续,可以看到下面是散的,因此还需要维护一个空闲的地址列表,这是缺点2

  • 缺点3就是需要停止整个程序,stop the world 体验差

复制(Copying)算法

  • 复制算法就是把一块内存分成两个区域,之前的幸存者区就是使用的复制算法

  • 如下图所示,复制算法从根节点开始递归遍历GC Roots的时候,把这些活着的对象全部复制到另外一个区域,复制完当前区域剩下的就全是垃圾了,直接全部回收,变成空闲区域,这样内存就是连续的,下次再递归遍历GC Roots的时候就把对象放到另外一个空区域

  • 优点:可以说没有标记和清除过程,因为遍历过程就直接复制了,根本没有标记对象什么的;保证空间连续性,不会出现碎片问题
  • 缺点:假设原本内存能放100个对象,用复制算法只能存50个对象,因为被一分为二了;第二个缺点:复制之后还需改变栈上对对象的引用指针,因为这是深拷贝,并不是移动。
  • 特别注意:如果系统中存活的对象非常多,比如老年代中使用复制算法,那结果就是极有可能全部对象都还活着,那复制算法就得把全部对象复制一遍,再改变一下栈中的所有的引用,反而没有优点了,所以复制算法在新生代中使用,因为新生代对象都是朝生夕死的。

标记-压缩(或标记-整理、Mark-Compact)算法

  • 也可以叫做标记-清除-压缩算法
  • 其实跟标记-清除算法完全一样,只不过在标记-清除算法的基础上,多加了一个内存碎片整理阶段,把内存整理成连续的,方便对象的分配

  • 优缺点如下

分代收集算法(前面算法结合)

  • 年轻代的幸存者区就是用的复制算法
  • 老年代是标记-清除、标记-整理算法相结合的

增量收集算法、分区算法

  • 增量收集算法,就是专门有一个垃圾回收的线程,可以跟主线程交替执行,不会造成STW

​​​​​​​

  • 分区算法

​​​​​​​

  • 最后

​​​​​​​

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值