前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(4)JVM——垃圾回收算法

(4)JVM——垃圾回收算法

作者头像
凡人飞
发布2020-09-20 20:14:19
3430
发布2020-09-20 20:14:19
举报
文章被收录于专栏:指缝阳光指缝阳光

一、概述

介绍:在程序运行过程中,程序计数器、虚拟机栈、本地方法栈 3 个区域随线程而生,随线程而灭,不用我们关注内存的回收。而 Java 堆和方法区不一样,此处的内存使用和回收是动态的,其中讲垃圾回收主要是在 Java 堆。

二、判断对象需要回收

2.1 引用计数算法

说明:给对象中添加一个引用计数器,没当有一个地方引用它时,计数器值就加 1 ;当引用失效时,计数器值减 1; 任务时刻计数器为 0 的对象就是不可能再被使用的。JVM 没用。

优点

  1. 实现简单
  2. 判定效率高

缺点

  1. 难解决对象之间相互循环引用的问题
2.2 可达性分析算法

说明:可达性分析算法就是根据找出一系列“GC Roots”的点,然后依次往下搜索,找出所有能找到的点。对于没能找到的点,就认为是不可达的,即需要回收的对象。如下图:

可达性分析算法
可达性分析算法

可作为 GC Roots 的对象包括如下:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中 JNI (即一般说的 Native 方法)引用的对象

三、垃圾回收算法

3.1 标记-清除算法

描述:算法分为“标记”和“清除”两个阶段:一、首先进行标记,即上面说的可达性分析算法; 二、统一回收所有被标记对象。过程如下

标记-清除算法
标记-清除算法

缺点

  1. 效率问题:标记和清除两个过程的效率都不高
  2. 空间问题:标记清除之后会产生大量不连续的内存碎片。碎片太多会导致以后需要分配大对象时,由于找不到这样的规整空间而提前触发垃圾收集
3.2 复制算法

描述:将可用内存划分为大小相等的两块,每次只使用其中的一块。当一块的内存用完了,就将存活的对象复制到另一块上面,然后把用过的那块一次清理掉。

优点:每次可以直接回收一半的内存,不会有内存碎片。分配也简单高效

缺点:使用时只有一半内存,比较浪费。

复制算法
复制算法

说明:HotSpot 虚拟机的新生代的回收采用的就是复制算法,不过划分分为一块较大的 Eden 空间和两块较小的 Survivor 空间。每次使用 Eden 和其中一个 Survivor ,回收时将存活对象复制到另一个 Survivor 上,然后释放用过的空间,并不断的循环 Survivor 作为使用区。比例 Eden : Survivor = 8 : 1。浪费空间为 10%, 如果存活对象大于 10% 的空间,会有老年代作内存分配担保(即将多余对象复制到老年代中)。

3.3 标记-整理算法

描述:对于老年代的对象来说,对象死亡率较低,因此复制算法不适用。“标记-整理”算法的标记步骤跟“标记-清除”算法一样,不过清除时会将存活对象移到一端集中,然后清除掉其他区域。

标记整理算法
标记整理算法
3.4 分代收集算法

描述:分代收集算法其实是对上面三种算法的应用,根据对象的存活特点,把 Java 堆分为新生代和老年代,然后根据各代的特点使用不同的收集算法:

  • 在新生代中,对象死亡率高,存活对象少,就使用复制算法
  • 在老年代中,对象存活率高,没有额外空间进行分配担保,就使用“标记-清理”或“标记-整理”算法
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概述
  • 二、判断对象需要回收
    • 2.1 引用计数算法
      • 2.2 可达性分析算法
      • 三、垃圾回收算法
        • 3.1 标记-清除算法
          • 3.2 复制算法
            • 3.3 标记-整理算法
              • 3.4 分代收集算法
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档