IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JVM详解【四】垃圾回收与算法 -> 正文阅读

[Java知识库]JVM详解【四】垃圾回收与算法

垃圾回收与算法

如何确定垃圾

??Java采用引用计数法和可达性分析法来确定对象是否应该被回收,其中,引用计数法容易产生循环引用的问题,可达性分析法通过根搜索算法(GC Roots Tracing)来实现。根搜索算法以一系列GC Roots的点作为起点向下搜索,在一个对象到到任何GC Roots都没有引用链相连时,说明其已经死亡。根搜索算法主要针对栈中的引用、方法区的静态引用和JNI中的引用展开分析,如图所示:
在这里插入图片描述

  1. 引用计数法

    ??在Java中如果要操作对象,就必须先获取对象的引用,因此可以通过引用计数法来判断一个对象是否可以被回收。在为对象添加一个引用时,引用计数器加 1;在为对象删除一个引用时,引入计数器减 1;如果一个对象的引用计数器为 0,则表示该对象没有被引用,可以被回收。

    ??引用计数法容易产生循环引用的问题。循环引用指两个对象相互引用,导致它们的引用一直存在,而不能被回收,如下图所示,Object 1与Object 2互为引用,如果采用引用计数法,则Object 1和Object 2由于互为引用,其引用计数器一直为 1,因而无法被回收。
    在这里插入图片描述

  2. 可达性分析法

    ??为了解决引用计数法的循环引用问题,Java还采用了可达性分析法来判断对象是否可以被回收。具体的做法是首先定义一些GC Roots对象,然后以这些GC Roots对象作为起点向下搜索,如果在GC Roots 和一个对象之间没有可达路径,则称该对象是不可达的。不可达对象要经过至少两次标记才能判定其是否可以被回收,如果两次标记后该对象仍然是不可达的,则将被垃圾回收器回收。

Java中常用的垃圾回收算法

??Java中常用的垃圾回收算法有标记清除(Mark-Sweep)、复制(Copy)、标记整理(Mark-Compact)和分代收集(Generational Collecting)这四种垃圾回收算法,如下图所示:

在这里插入图片描述

  1. 标记清除算法

    ??标记清除算法是基础的垃圾回收算法,其过程分为标记和清除两个阶段。在标记阶段标记所有需要回收的对象,在清除阶段清除可回收的对象并释放其所占用的内存空间,如下图所示:
    在这里插入图片描述
    ??由于标记清除算法在清理对象所占用的内存空间后并没有重新整理可用的内存空间,因此如果内存中可被回收的小对象过多,则会引起内存碎片化的问题,继而引起大对象无法获得连续可用内存空间的问题。

  2. 复制算法

    ??复制算法是为了解决标记清除算法内存碎片化的问题而设计的。复制算法首先将内存划分为两块大小相等的内存碎片,即区域 1 和区域 2 ,新生成的对象都被存放在区域 1 中,在区域 1 内的对象存储满后会对区域 1 进行一次标记,并将标记后仍然存活的对象全部复制到区域 2 中,这时区域 1 将不存在任何存活的对象,直接清理整个区域 1 的内存即可,如下图所示:

    在这里插入图片描述
    ??;复制算法的内存清理效率高且易于实现,但由于同一时刻只有一个内存区域可用,即可用的内存空间被压缩到原来的一半,因此存在大量的内存浪费。同时,在系统中大量长时间存货的对象时,这些对象将在内存区域 1 和内存区域 2 之间来回复制而影响系统的运行效率。因此,该算法只在对象为“朝生夕死”状态时运行效率较高。

  3. 标记整理算法

    ??标记整理算法结合了标记清除算法和复制算法的优点,其标记阶段和标记清除算法的标记阶段相同,在标记完成后将存活的对象移到内存的另一端,然后清楚该端的对象并释放内存,如下图所示:
    在这里插入图片描述

  4. 分代收集算法

    ??无论是标记清除算法、复制算法还是标记整理算法,都无法对所有类型(长生命周期、短生命周期、大对象、小对象)的对象都进行垃圾回收。因此,针对不同的对象类型,JVM采用了不同的垃圾回收算法,该算法被称为分代收集算法。

    ??分代收集算法根据对象的不同类型将内存划分为不同的区域,JVM将堆划分为新生代和老年代。新生代主要存放新生成的对象,其特点是对象数量多但是生命周期短,在每次进行垃圾回收时都有大量的对象被回收;老年代主要存放大对象和生命周期长的对象,因此可回收的对象相对较少。因此,JVM根据不同的区域对象的特点选择了不同的垃圾回收算法。

    ??目前,大部分JVM在新生代都采用了复制算法,因为在新生代中每次进行垃圾回收时都有大量的对象被回收,需要复制的对象(存活的对象)较少,不存在大量的对象在内存中被来回复制的问题,因此采用复制算法能安全、高效地回收新生代大量的短生命周期的对象并释放内存。

    ??JVM将新生代进一步划分为一块较大的Eden区和两块较小的Survivor区,Survivor区又分为SurvivorFrom区和SurvivorTo区。JVM在运行过程中主要使用Eden区和SurvivorFrom区,进行垃圾回收时会将在Eden区和SurvivorFrom区中存活的对象复制到SurvivorTo区,然后清理Eden区和SurvivorFrom区的内存空间,如下图所示:
    在这里插入图片描述

    ??老年代主要存放生命周期较长的对象和大对象,因而每次只有少量非存活的对象被回收,因而在老年代采用标记清除算法。

    ??在JVM中还有一个区域,即方法区的永久代,永久代用来存储Class类、常量、方法描述等。在永久代主要回收废弃的常量和无用的类。

    ??JVM内存中的对象主要被分配到新生代的Eden区和SurvivorFrom区,在少数情况下会被直接分配到老年代。在新生代的Eden区和SurvivorFrom区的内存空间不足时会触发一次GC,该过程被称为MinorGC。在MinorGC后,在Eden区和SurvivorFrom区中存活的对象被复制到SurvivorTo区,然后Eden区和SurvivorFrom区被清理。如果此时在SurvivorTo区无法找到连续的内存空间存储某个对象,则将这个对象直接存储到老年代。若Survivor区的对象进过一次GC后仍然存活,则其年龄加 1.在默认情况下,对像在年龄达到15时,将被转移到老年代。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:29:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:45:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码