千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:大连千锋IT培训  >  技术干货  >  JVM垃圾回收机制是什么?

JVM垃圾回收机制是什么?

来源:千锋教育
发布人:bjq
时间: 2023-03-09 15:54:00

  JVM垃圾回收机制是什么?

JVM垃圾回收机制是什么

  一. 什么是垃圾回收(GC)

  JVM的内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。

  其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生、随线程而灭,因此这几个区域的内存分配和回收都具备确定性,就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。而Java堆区和方法区则不一样、不一样,这部分内存的分配和回收是动态的,我们需要对不在使用的对象进行处理回收过期的对象(垃圾)从而释放JVM内存空间

  二. 什么时候回收

  2.1 概述

  在垃圾回收之前,我们必须确定的一件事就是对象是否存活?这就牵扯到了判断对象是否存活的算法

  了。

  2.2 引用计数算法

  给对象中添加一个引用计数器,每当有一个地方引用它时,计数器+1,当引用失效,计数器-1.任何时刻

  计数器为0的对象就是不可能再被使用的

  优点:实现简单,判定效率高效,被actionscript3和python中广泛应用。

  缺点:无法解决对象之间的相互引用问题。java没有采纳

  2.3 可达性分析算法

  通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GCRoots没有任何引用链相连的时候,则证明此对象是不可用的。

  比如如下,右侧的对象是到GCRoot时不可达的,可以判定为可回收对象

  在java中,可以作为GCRoot的对象包括以下几种

  * 虚拟机栈中引用的对象。

  * 方法区中静态属性引用的对象。

  * 方法区中常量引用的对象。

  * 本地方法中JNI引用的对象。

  基于以上,我们可以知道,当当前对象到GCRoot中不可达时候,即会满足被垃圾回收的可能。

  那么是不是这些对象就非死不可,也不一定,此时只能宣判它们存在于一种“缓刑”的阶段,要真正的宣告一个对象死亡。至少要经历两次标记

  第一次:对象可达性分析之后,发现没有与GCRoots相连接,此时会被第一次标记并筛选。

  第二次:对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,此时会被认

  定为没必要执行。

  三. 如何回收

  3.1 概述

  上述的两点讲解之后,我们大概明白了,哪些对象会被回收,以及回收的依据是什么,但回收的这个工作实现起来并不简单,首先它需要扫描所有的对象,鉴别谁能够被回收,其次在扫描期间需要 ” stop the world“ 对象能被冻结,不然你刚扫描,他的引用信息有变化,你就等于白做了

  3.2 分代回收

  我们从一个object1来说明其在分代垃圾回收算法中的回收轨迹

  step01 object1新建,出生于新生代的Eden区域

  step02 minor GC,object1 还存活,移动到Fromsuvivor空间,此时还在新生代

  step03

  minor GC,object1 仍然存活,此时会通过复制算法,将object1移动到ToSuv区域,此时object1

  的年龄age+1

  step04 minor GC,object1 仍然存活,此时survivor中和object1同龄的对象并没有达到survivor的一半, 所以此时通过复制算法,将fromSuv和Tosuv 区域进行互换,存活的对象被移动到了Tosuv

  step05 minor GC,object1 仍然存活,此时survivor中和object1同龄的对象已经达到survivor的一半以上 (toSuv的区域已经满了),object1被移动到了老年代区域

  step06

  object1存活一段时间后,发现此时object1不可达GcRoots,而且此时老年代空间比率已经超过了阈

  值,触发了majorGC(也可以认为是fullGC,但具体需要垃圾收集器来联系),此时object1被回收了。

  fullGC会触发 stop the world

  在以上的新生代中,我们有提到对象的age,对象存活于survivor状态下,不会立即晋升为老生代对

  象,以避免给老生代造成过大的影响,它们必须要满足以下条件才可以晋升

  1、minor gc 之后,存活于survivor 区域的对象的age会+1,当超过(默认)15的时候,转移到老年代

  2.、动态对象,如果survivor空间中相同年龄所有的对象大小的综合和大于survivor空间的一半,

  年级大于或等于该年级的对象就可以直接进入老年代

  以上采用分代垃圾收集的思想,对一个对象从存活到死亡所经历的历程。期间,在新生代的时刻,会用到复制算法,在老年代时,有可能会用到标记-清楚算法(mark-sweep)算法或者标记-整理算法,这些都是垃圾回收算法基于不同区域的实现,我们看下这几种回收算法的实现原理

  四. 垃圾回收算法

  4.1 标记清除法

  标记清除法是垃圾回收算法的思想基础。标记清除算法将垃圾分为两个阶段:标记阶段和清除阶段。

  标记阶段,通过根节点,标记所有从根节点开始的可达对象,未标记过的对象就是未被引用的垃圾对象。清除阶段,清除所有未被标记的对象

  4.2 复制算法 Copying

  复制算法是,将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在适用的内存中存活对象复制到未使用的内存块,然后清除使用的内存块中所有的对象。

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

  标记压缩算法是一种老年代的回收算法。

  标记阶段和标记清除算法一致,对可达对象做一次标记。

  清理阶段,为了避免内存碎片产生,将所有的存活对象压缩到内存的一端

  五. 垃圾收集器

  5.1 概述

  垃圾收集器是内存回收的具体实现,不同的厂商提供的垃圾收集器有很大的差别,一般的垃圾收集器都会作用于不同的分代,需要搭配使用。以下是各种垃圾收集器的组合方式

  5.2 各种组合的优缺点

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

什么是Java循环?

2023-03-30

switch语句的case和default有顺序吗?

2023-03-30

SpringBoot中使用redis 新手入门

2023-03-29

最新文章NEW

10分钟学会阿里OSS对象存储

2023-03-07

没有弹性盒,如何玩转移动端?

2023-02-13

浮动布局详解

2023-02-10

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>