H5W3
当前位置:H5W3 > java > 正文

【Java】Java虚拟机-垃圾回收

原文链接

回收的是什么?
答:运行程序中没有任何指针引用的对象,这个对象就是需要被回收的垃圾

垃圾回收算法

标记阶段

  • 在GC执行垃圾回收之前,首先需要区分出内存中那些是存活的对象,那些是已经死亡的对象。只有被标记为已死亡的对象,GC才会在执行垃圾回收时,释放掉其存活所占用的内存空间。此过程被称为垃圾标记阶段
  • 当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡
  • 判断对象存活的有两种方式:引用计数算法可达性分析算法

引用计数算法(Reference Counting)

  • 描述:对每一个对象保存一个整型的引用计数器属性,用于记录对象被引用的的情况
  • 优点:

    • 实现简单,垃圾对象便于辨识
    • 判定效率高,回收没有延迟性
  • 缺点:

    • 需要单独的字段存储计数器,增加了存储空间
    • 每次赋值都需要重新更新计数器,增加了时间开销
    • 无法解决循环引用

可达性分析算法

  • 解决了引用计数算法中循环引用的问题,防止内存泄露
  • 可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达
  • 使用该算法后,内存中的存活对象都会被根集合直接或间接的连接着,搜索走过的路径称为引用链
  • 如果没有任何引用链,则不可达,说明对象已死亡,可以标记为垃圾对象

GC Roots包含以下几类元素:

  1. 虚拟机栈中引用的对象
  2. 本地方法(native方法)中引用的对象
  3. 方法区中常量引用的对象
  4. 被同步锁synchronized持有的对象
  5. Java虚拟机内部的引用

    • 基本数据类型对应的Class对象常驻异常对象和系统类加载器
  6. 反映Java虚拟机内部情况的JMXBean、 JVMTI中注册的回调、本地代码缓存等

【Java】Java虚拟机-垃圾回收

finalization机制

  • 提供对象被销毁之前的自定义处理逻辑
  • 当垃圾回收器发现没有引用指向一个对象,总会先调用这个对象的finalize()方法
  • finalize()方法允许在子类中被重写,用于在对象被回收时进行资源释放。例如:关闭文件,断开数据库连接

清除阶段

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

执行过程:当堆中的内存空间被耗尽的时候,就会停止整个程序(stop the world),然后进行标记和清除工作。

标记:Collector从引用根节点开始遍历,标记所有被引用的对象,并将这些对象记录在Header中。(找出在程序中被引用的对象,并清除其他的)

清除:Collector从堆内存中从头到尾的进行线性遍历,如果发现某个对象在Header中没有标记为可达对象,则将其回收。(将不可达对象存放在空闲列表中,当有新对象进入时,将其位置覆盖)

缺点:

  • 效率不高
  • 在进行GC时,需要停止整个应用程序,导致用户体验差
  • 清理出来的空闲内存是不连续的,产生内存碎片且需要维护一个空闲列表

复制算法(Copying)

执行过程:当A空间同时存在可达和不可达对象时,将可达对象复制到B空间并保证空间的连续,后清除A空间的所以对象

优点:

  • 没有标记清除过程,实现简单
  • 将存在引用关系的对象复制过去后,保证空间的连续性,不会存在碎片

缺点:

  • 需要两倍的内存空间
  • 对于存活对象的数量远大于垃圾对象数量时,此清除算法效率差。

标记-压缩算法(Mark-Compact)

执行过程:

  1. 从根节点开始标记存在引用关系的对象
  2. 将这些对象压缩到内存的一端并按顺序排放
  3. 清除边界外的所以对象

优点:

  • 对于“标记-清除算法”,由于使用了压缩功能,当有新对象分配内存时,JVM只需要持有一个内存的起始地址即可
  • 对于“复制算法”,减少了内存空间的占用

缺点:

  • 对比“复制算法”,效率低
  • 在移动存在引用关系的对象时,需要调整引用的地址
  • 移动过程中,需要全程暂停用户程序(stop the world)

分代收集算法

根据年轻代和老年代的特点使用不同的内存回收算法

年轻代:

针对年轻代空间小,对象生命周期短,收集频繁和存活率低的特点,使用复制算法可以高效完成内存回收,复制算法使用率不高的问题,通过两个survivor的设计可以有效的缓解。

老年代:

老年代是空间大,对象生命周期长,存活率高和回收不频繁,使用标记-清除算法或标记-清除算法和标记-压缩算法结合完成内存空间的回收。

finalize

内存溢出 和内存泄露

本文地址:H5W3 » 【Java】Java虚拟机-垃圾回收

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址