Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JVM垃圾回收之垃圾收集算法,程序员必须掌握的知识

JVM垃圾回收之垃圾收集算法,程序员必须掌握的知识

作者头像
黎明大大
发布于 2020-09-08 09:22:19
发布于 2020-09-08 09:22:19
42100
代码可运行
举报
文章被收录于专栏:java相关资料java相关资料
运行总次数:0
代码可运行
垃圾算法分为哪几种

1.标记/清除算法 2.复制算法 3.标记/整理算法 jvm采用的是"分带收集算法"对不同的区域使用不同的算法

什么时候会触发垃圾回收

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有三种类型:Minor GC和Major GC和Full GC。 Minor GC:新生代回收GC Major GC: 老年代回收GC Full GC: 新年代 + 老年代的结合版GC

Minor GC

一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Full GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC

分代收集算法

分带收集算法:是根据对象的存活周期的不同,将内存划分为几块,新生代和老年代,这样就可以根据不同的年代采用不同的收集算法。 新生代对象朝生夕死,对象数量何其之多,只要重点扫描这个区域,那么就可以大大提高垃圾收集的效率,另外老年代对象存储比较久,无需经常扫描,避免扫描所导致的开销

新生代:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。

大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个)(YGC,年轻代垃圾回收),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。

解释下,堆大小=新生代+老年代,新生代与老年代的比例为1:2,新生代细分为一块较大的Eden空间和两块较小的Survivor空间,分别被命名为from和to。

老年代
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
复制算法

如果jvm使用了复制算法,一开始就会将可用内存分为两块,from域和to域, 每次只是使用from域,to域则空闲着。当from域内存不够了,开始执行GC操作,这个时候,会把from域存活的对象拷贝到to域,然后直接把from域进行内存清理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、当Eden区满的时候,会触发第一次young gc,把还活着的对象拷贝到Survivor From区;当Eden区再次触发young gc的时候,会扫描Eden区和From区域,对两个区域进行垃圾回收,经过这次回收后还存活的对象,则直接复制到To区域,并将Eden和From区域清空。
2、当后续Eden又发生young gc的时候,会对Eden和To区域进行垃圾回收,存活的对象复制到From区域,并将Eden和To区域清空。
3、可见部分对象会在From和To区域中复制来复制去,如此交换15次(JVM参数MaxTenuringThreshold决定,这个参数默认是15,每次复制都会进入加一),最终如果还是存活,就存入到老年代

注意: 万一存活对象数量比较多,那么To域的内存可能不够存放,这个时候会借助老年代的空间。

标记/清除算法

注意:当对象的年龄达到了15 才会进入到老年代

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
该算法有两个阶段。
1. 标记阶段:找到所有可访问的对象,做个标记
2. 清除阶段:遍历堆,把未被标记的对象回收

优缺点: 优点

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
可以解决循环引用的问题
必要时才回收(内存不足时)

缺点

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
回收时,应用需要进行挂起,也就是stop the wrold
标记和清除效率不高,尤其要扫描的对象比较多的时候,会造成内存碎片(会导致明明有内存空间,但是由于不连续,申请稍微大一些的对象无法做到)
标记/整理算法

标记清除算法和标记压缩算法非常相同,但是标记压缩算法在标记清除算法之上解决内存碎片化

它的压缩算法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
任意顺序 : 即不考虑原先对象的排列顺序,也不考虑对象之间的引用关系,随意移动对象;
线性顺序 : 考虑对象的引用关系,例如a对象引用了b对象,则尽可能将a和b移动到一块;
滑动顺序 : 按照对象原来在堆中的顺序滑动到堆的一端。

优点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
解决了内存碎片的问题

缺点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
由于移动了可用对象我,需要重新更新引用

总结:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
新生代:因为对象的存活期比较时间比较短,所以采用复制收集算法效率比较快
老年代:因为对象存活的时间比较长,没有额外的空间给他担保,故采用标记/清除算法和标记/整理算法
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JVM中垃圾收集算法总结
  通过前面的介绍我们了解了对象创建和销毁的过程。那么JVM中垃圾收集器具体对对象回收采用的是什么算法呢?本文主要记录下JVM中垃圾收集的几种算法。
用户4919348
2019/04/02
4360
JVM中垃圾收集算法总结
JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)
  按照套路是要先装装X,谈谈JVM垃圾回收的前世今生的。说起垃圾回收(GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史比Java久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术。设计和优化C++这门语言的专家们要长点心啦~~
哲洛不闹
2019/03/11
1.5K0
JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)
JVM的4种垃圾回收算法、垃圾回收机制与总结[通俗易懂]
JVM的4种垃圾回收算法、垃圾回收机制与总结 – 知乎 https://zhuanlan.zhihu.com/p/54851319
全栈程序员站长
2022/11/07
11.5K0
JVM的4种垃圾回收算法、垃圾回收机制与总结[通俗易懂]
JVM 垃圾回收算法
在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。
一个会写诗的程序员
2020/05/18
1.1K2
JVM 垃圾回收算法
深入理解JVM—JVM垃圾回收机制[通俗易懂]
如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
全栈程序员站长
2022/08/31
1.6K0
《深入理解java虚拟机》笔记(5)垃圾回收算法及垃圾收集器
算法:分为标记和清除两个阶段,首先标记出所有需要回收的对象,再对标记对象进行回收。
夕阳也是醉了
2023/10/16
1670
《深入理解java虚拟机》笔记(5)垃圾回收算法及垃圾收集器
JVM系列--JVM调优 分代垃圾回收详述
来源:https://www.iteye.com/blog/pengjiaheng-524024
田维常
2020/02/14
4160
JVM系列--JVM调优 分代垃圾回收详述
垃圾收集算法
在前面的引用计数法和可达性算法一文中,我们讲了一个引用要被回收需要达到的条件以及怎么判断一个引用是否要被回收。了解了这些知识,就到了今天要讲的垃圾收集算法。
飞翔的竹蜻蜓
2020/07/08
7430
垃圾收集算法
jvm垃圾回收详解_java 垃圾回收器
JVM 会自动帮程序员进行垃圾回收,并不需要程序员手动的进行垃圾回收(C++等语言需要自己手动回收垃圾),了解 JVM 的垃圾回收,可以帮程序员写出占用内存更小、更高效的程序。
全栈程序员站长
2022/10/01
1.2K0
jvm垃圾回收详解_java 垃圾回收器
java垃圾回收机制原理_java垃圾回收的缺点
最近做一个ETL的项目模块,经常由于查询数据量比较大用消息中间件MQ时引起了内存溢出的报错。做完后没事研究了一下JVM和垃圾回收的相关知识点。
全栈程序员站长
2022/11/08
5680
java垃圾回收机制原理_java垃圾回收的缺点
JVM垃圾收集之——垃圾收集算法
链接: JVM垃圾收集之——怎样判定一个对象是不是垃圾 接上篇,介绍完怎样判定一个对象是不是垃圾之后,就该瞅一瞅垃圾是怎样回收的了 首先我们要知晓,垃圾收集是建立在两个分代假说之上的:
向着百万年薪努力的小赵
2022/12/02
4930
JVM垃圾收集之——垃圾收集算法
资深架构师吐血总结Java垃圾收集算法
由于垃圾收集算法的实现涉及大量的程序细节,而且每个平台的虚拟机操作内存的方法又各不相同,因此博客中不过多的讨论算法的实现,只是介绍几种算法的思想以及发展。
本人秃顶程序员
2019/05/09
4100
资深架构师吐血总结Java垃圾收集算法
JVM 垃圾回收详解
内存泄漏:又叫“存储泄漏”,对象不会在被程序使用了,但是GC又不能回收他们。例如:IO流不适用了但是没有被close、数据库连接JDBC没有被close。这些对象不会被回收就会占据内存,大量的此类对象存在,也是导致内存溢出的原因。
程序员子龙
2023/12/18
2460
深入理解java垃圾回收机制
  Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。
lyb-geek
2018/07/26
5470
深入理解java垃圾回收机制
深入理解JVM - 垃圾回收算法
这一期讲述垃圾回收的算法。我们根据分代的理念讲述一下JVM是使用什么算法对于不同分代的对象进行垃圾回收的的,同样内容十分基础,但是对于学习JVM后续的内容十分重要。
阿东
2021/08/16
1.9K0
深入理解JVM - 垃圾回收算法
一文理解JVM(内存、垃圾回收、性能优化)解决面试中遇到问题
Java堆是java虚拟机所管理内存中最大的一块内存空间,处于物理上不连续的内存空间,只要逻辑连续即可,主要用于存放各种类的实例对象。该区域被所有线程共享,在虚拟机启动时创建,用来存放对象的实例,几乎所有的对象以及数组都在这里分配内存(栈上分配、标量替换优化技术的例外)。
lyb-geek
2019/12/24
6800
一文理解JVM(内存、垃圾回收、性能优化)解决面试中遇到问题
深入理解JVM垃圾收集机制(JDK1.8)
垃圾收集算法 标记-清除算法 最基础的收集算法是“标记-清除”(Mark-Sweep)算法,分两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。 不足:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能导致以后在程序运行过程需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一个的垃圾收集动作。 复制算法 为了解决效率问题,一种称为复制(Copying)的收集算法出现了,它将可用内存按容量划分为大
Ryan-Miao
2018/03/21
4.9K0
深入理解JVM垃圾收集机制(JDK1.8)
Java虚拟机:垃圾回收机制与垃圾收集器
JVM内存区域的程序计算器,虚拟机栈、本地方法栈的生命周期是和线程同步的,随着线程的销毁而自动释放内存,所以只有堆和方法区需要GC,方法区主要是针对常量池的回收和对类型的卸载,堆区针对的是不再使用的对象进行回收内存空间。我们常说的GC一般指的是堆区的垃圾回收,堆内存空间可以进一步划分新生代和老年代,新生代会发生Minor GC,老年代会发生Full GC。
全栈程序员站长
2021/04/13
3870
Java虚拟机:垃圾回收机制与垃圾收集器
JVM垃圾回收(下)
接着上一篇,介绍完了 JVM 中识别需要回收的垃圾对象之后,这一篇我们来说说 JVM 是如何进行垃圾回收。
健程之道
2019/11/02
4070
Java垃圾回收器与内存分配策略
上一篇JVM内存模型讲述了Java虚拟机在运行时所管理的内存划分下的每个数据区域的各自用途,以及创建和销毁时间。当需要排查各种内存泄漏、内存溢出问题时,当来及收集成为系统达到更高并发量的瓶颈时,我们需要对JVM的GC机制和内存分配又更多的了解,这边文章是在上一篇文章的基础之上讲述了Java垃圾回收器与内存分配策略。
静默加载
2020/05/29
9390
推荐阅读
相关推荐
JVM中垃圾收集算法总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验