3-JVM垃圾回收算法和垃圾收集器

简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 垃圾回收算法和垃圾收集器 1.什么是垃圾回收 对于内存当中无用的对象进行回收,如何去判断一个对象是不是无用的对象。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


1.什么是垃圾回收

对于内存当中无用的对象进行回收,如何去判断一个对象是不是无用的对象。

引用计数法:

每个对象中都会存储一个引用计数,每增加一个引用就+1,消失一个引用就-1。当引用计数器为0时就会判断该对象是垃圾,进行回收。

但是这样会有一个弊端。就是当有两个对象互相引用时,那么这两个对象的引用计数器都不为0,那么就不会对其进行回收。

可达性分析:

1

判断某个对象是否可到达。有两种方式判断是否可到达:

(1).直接引用(上帝视角GC Roots):就是虚拟机栈帧中的局部或本地变量表、类加载器、static成员、常量引用、Thread等等中的引用直接到达。

为什么本地或局部变量表里面的变量有它出发就可以用来判断GC Roots的判断标准呢?

因为只用它表示这个栈帧正在被压栈,正在被使用,这个时候再去回收这个对象不是疯了嘛!!!同理static、常量也是一样的道理。

(2).间接引用:通过别人的引用来达到。

并发的可达性分析(并发标记、浮动垃圾)

2.垃圾回收的策略

垃圾收集算法

  • 标记-清除

先标记

2

后清除

3

弊端一:会有空间碎片问题,空间不连续;这时如果有大一点的对象进来,发现没有连续的空间内存去进行分配,就会再一次的触发垃圾回收机制。

弊端二:在标记和清除的过程中、会扫描整个堆内存;会比较耗时。

有点:简单、明了、好操作。

  • 标记-复制

一开始将这个内存空间一分为二,两边大小相等,一边使用中的,一边是保留区未使用的。划分为这样示例图:

4

在标记和清除之后,将存活的对象复制到另外一边,在将先前的一边数据全部清除掉。

5

之后以此反复、两个循环往返。

类似于堆内存中的新生代(Young)区中的Survivor区中的S0、S1,所以堆内存中的新生代(Young)区一定用的就是复制算法。

  • 标记-整理

先标记

6

后整理。

7

整理移动之后会得到一片连续的可分配内存空间。解决了空间碎片的问题,但是这种方式在标记和整理移动的过程中也是耗时的。


垃圾收集器:评判一个垃圾收集好坏和调优关注的是【高吞吐量、少停顿时间、少垃圾回收次数】

串行:Serial系列;

并行【吞吐量优先】:Paraller系列;

吞吐量:用户代码执行的时间 / (用户代码执行的时间+垃圾收集时间)99/(99+1)=99%。

适用于后台运算,不需要太多的交互场景。

并发【停顿时间优先】:CMS、G1;

适用于用户交互较多的场景,给用户更好的体验感;如Web应用。

JVM垃圾收集器调优的原则:尽可能在停顿时间较低的情况下,追求高的吞吐量和少的垃圾回收次数。

官方JVM垃圾收集器建议:

1.使用默认垃圾收集器

2.调整JVM堆的大小

3.如果应用程序内存空间比较小(比如100MB),直接选择SerialGC串行收集器。-XX:+UseSerialGC

如果应用程序运行在一个单核的CPU,和没有停顿时间要求的情况下;可以让JVM自己去选择或者选择SerialGC串行收集器。-XX:+UseSerialGC

如果应用程序更加关注的吞吐量也没有停顿时间要求的情况下,可以让JVM自己去选择或者选择并行的ParallelGC。-XX+UseParallelGC

如果应用程序对停顿时间要求比较高(比如小于1秒钟的时间),那么就选择CMS或者G1的收集器。-XX:+UseConcMarkSweepGC 或 -XX:+UseG1GC

8

G1(Garbage-First):JDK7出现,JDK8推荐使用,JDK9默认垃圾收集器。

G1的整个垃圾收集并清理的过程阶段大体上和CMS收集器是不变的。在最后一个阶段进行删选回收(选择性的回收,进行优先级的回收:优先回收区域(Region)内存活对象较少的)。

9

重新设计内存空间如图所示:

10

整个内存划分为一个个大小相等的区域(Region)。逻辑上对这些区域(Region)进行标记,这些标记有Eden区,Survivor区和Old区。这时的物理空间上就不在是连续空间了;之前的空间划分都是连续的空间。假如回收掉某个Old区的数据,这时这个区域也可能会标位Survivor区或者Eden区。

区域(Region)内还有一个记录rememberd Set。以前会全盘扫描堆内存,是比较耗时的。这时会记录一个对象存活的地方,对象的引用指向;这样就不用在全盘扫描了耗时比较低。


Young Generation(新生代)- 垃圾收集算法一定是标记-复制算法的实现

Serial:JDK1.3出现的,单线程收集,STW。那时候的CPU还是单核CPU。单线程处理效率比较高,在进行垃圾回收的时候,会暂停业务线程,等待垃圾回收完成之后,在让业务线程再继续执行。会搭配老年代的SerialOld配合使用。

这时会出现Stop The World(STW)

11

ParNew:并行垃圾收集器多个垃圾线程一起跑,STW ,停顿时间较多,更加关注吞吐量

复制算法、并行多线程垃圾收集器,解决了单线程的局限性,但是还是Stop The World(STW)。

12

ParallelScavenge

同上


Tenured Generation(老年代)- 这里是标记-清除、或标记-整理的算法实现

CMS:JDK5出现的,并发收集,两个阶段会STW(初始标记、重新标记),更加关注停顿时间。在JDK8中已经不推荐使用,JDK8推荐使用G1收集器。

并发:垃圾收集线程和业务代码线程一起跑。但是并不能做到全程一起执行。

因为垃圾收集线程在执行的时候对垃圾进行标记,这时业务代码线程也在执行,也会产生新的垃圾。至少在垃圾收集线程在进行标记的阶段,业务代码暂定的是不执行的。

13

划分为四个阶段:初始标记、并发标记、重新标记、并发清理。

初始标记:第一阶段会Stop The World(STW)。这个阶段执行的时间是非常快的,如果开启多个线程,会消耗线程之前的切换反而会增加时间成本。

并发标记:第二阶段就是可达性分析,对第一阶段的垃圾进行跟踪。在这个阶段垃圾线程和业务线程是一起执行的;为啥可以一起执行呢?因为在第一阶段初始标记完成后大局已定,第二阶段的并发标记只是做增量的更新。如果此时又产生了垃圾那么就是浮动垃圾(把原本消亡的对象错误的标记为存活状态),只能等待下次清理。

重新标记:第三阶段这时会停止业务代码的线程Stop The World(STW),会多线程垃圾收集器并行一起跑,一起执行。

并发清理:第四阶段垃圾收集线程和业务代码线程再次一起执行,一起跑。

特点:并发收集,停顿时间较少。

缺点:会产生浮动垃圾。其次由于采用的是标记-清除这样的算法会产生大量的空间碎片。

Serial Old:串行的

14

Paraller Old:并行的

如何查看当前JAVA程序应用使用的是什么垃圾收集器:

15

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-05-11
本文作者:赵小胖0914
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关文章
|
27天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
53 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
25天前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
26天前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
46 2
|
28天前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
29天前
|
算法 Java
谈谈HotSpot JVM 中的不同垃圾回收器
【10月更文挑战第5天】理解 HotSpot JVM 中的不同垃圾回收器(如 CMS、G1 和 ZGC)的区别,需要深入了解它们的设计原理、工作方式和应用场景。以下是对这三个垃圾回收器的简要概述以及一个示例 Java 程序,虽然示例程序本身不能直接展示垃圾回收器的内部机制,但可以帮助观察不同垃圾回收器的行为。
17 1
|
1月前
|
存储 算法 Java
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
46 2
|
23天前
|
算法 JavaScript 前端开发
垃圾回收算法的原理
【10月更文挑战第13天】垃圾回收算法的原理
21 0
|
2月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
108 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
2月前
|
监控 算法 Java
深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
|
1月前
|
存储 Java PHP
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
52 0
下一篇
无影云桌面