JVM (标记-清除算法、复制算法、标记-整理算法、分代收集算法、分区算法)...

2023-11-03 12:59

本文主要是介绍JVM (标记-清除算法、复制算法、标记-整理算法、分代收集算法、分区算法)...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JVM类加载过程与双亲委派机制与类加载器与类字节码详解

  • 目录
    • 概 述
      • 可达性分析算法(Reachability Analysis):
      • .链接
      • 可达性分析算法GC Roots的对象包含有哪些?
      • 如何判断对象是否存活
  • 相关工具如下:
    • 分析:
  • 小结:
  • 参考资料和推荐阅读

LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code and KPI, Keep progress,make a better result.
Survive during the day and develop at night。

目录

概 述

引用计数算法(Reference Counting):
实现比较简单,对每一个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
优点:实现比较简单,很容易判断是否是垃圾,判断效率高,回收没有延迟性。
缺点:

    需要单独的字段来存储,增加空间的开销;每次值的更新需要更新计数器,伴随加法和减法操作,增加一定时延;引用计数器有一个严重的问题,无法处理循环引用的问题,导致不知道是否是垃圾还是存活类似A->B->A的问题,会造成内存泄漏。

可达性分析算法(Reachability Analysis):

一、类加载过程
加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。
类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。
通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有如下几种来源。

1.从本地文件系统加载class文件,这是前面绝大部分示例程序的类加载方式。
2.从JAR包加载class文件,这种方式也是很常见的,前面介绍JDBC编程时用到的数据库驱动类就放在JAR文件中,JVM可以从JAR文件中直接加载该class文件。
3.通过网络加载class文件。
4.把一个Java源文件动态编译,并执行加载。
类加载器通常无须等到“首次使用”该类时才加载该类,Java虚拟机规范允许系统预先加载某些类。

.链接

可达性分析算法是java采用来判断对象是否存在的算法,通过判断"GC Roots"是否被直接或间接引用,这种会被可达性分析通过搜索路劲找到,而这个路劲叫引用链(Reference Chain),如果被存在则证明是可达的,若不是被引用则证明对象是可以被回收的。依据只是判断该GC Roots上在的这个对象是否存活,实现稍微比较复杂。

可达性分析算法GC Roots的对象包含有哪些?

可达性分析算法GC Roots的对象包含有哪些?
虚拟机栈引用的对象

    本地方法栈内JNI(本地方法)引用的对象方法区中常量引用的对象(字符串常量池)所有被同步锁synchronized持有的对象Java虚拟机内部的引用

如何判断对象是否存活

对象有三种状态:可触及、可复活、不可触及,分别代表如下:
可触及:从根节点开始,可以达到这个对象;
可复活:对象的所有引用都被释放,但是对象有可能在finalize()中复活;
不可触及:对象finalize()被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为finalize()只会被调用一次。
对象被回收前,首先可达性分析到这个对象是否有与GC Roots的引用链,如果没有会被打上第一次标记,然后判断是否有必要执行finalize,如果被执行过或没必要就直接被垃圾回收了。如果有必要,执行后会被入到F-Queue这个队列中,然后逃过一次被GC。等到下一次GC的时候会对F-Queue这个对队列再做一次的标记,如果这次再发现没有引用链就会被直接GC回收了。
在这里插入图片描述
在这里插入图片描述
Java 中都有哪些引用类型?
强引用:发生 gc 的时候不会被回收。new

软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。SoftReference

弱引用:有用但不是必须的对象,在下一次GC时会被回收。WeakReference

虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用 PhantomReference 实现虚引用,虚引用的用途是在 gc 时返回一个通知。

PhantomReference pr = new PhantomReference (object, queue);

可达性分析算法是JAVA采用判断对象存活的算法。
三种算法的对比?
对比名称

标记-清除

标记-整理

标记-复制

速度

中等

最慢

最快

空间开销

少(会产生碎片)

少(不会产生碎片)

需要对象2倍大小

移动对象

分代收集算法(Generational Collection)
背景:由于每个收集的算法都没办法符合所有的场景,就好比每个对象所在的内存阶段不一样,被回收的概率也不一样,比如在新生代,基本可以说90%以上的都会被回收,而到老年代接近一半以上的对象则是一半存活的,所以针对这两种不同的场景,回收的策略肯定有所不一样,所以引发而出的就是分代收集算法,根据新生代和老年代不同的场景而用不同的算法,比如新生代用复制算法,而老年代则用标记-整理算法。

HotSpot基于分代的概念,GC所使用的内存回收算法是根据新生代和老年代的特点。

新生代(Yong Gen)

年轻代特点:区域相对老年代较小,对象生存周期短,存活率低,回收频繁。所以适合-标记-复制算法;

老年代(Tenured Gen)

老年代特点:区域较大,对象生命周期长、存活率高,回收不频繁,所以更适合-标记-整理算法;

像CMS、G1这些垃圾收集器都属于这个分代思想演化而来。

增量收集算法(Incremental Collecting):
现有的所有的算法都可能会导致停机-Stop the World的状态,这样会导致所有程序都被挂起,这样会影响用户体验和系统的稳定性。所以增加增量收集算法就是解决每次GC的时候导致停机的问题,其思想是每次垃圾收集中对某一个区域进行收集,再切到用户的线程,直接垃圾收集完成。这样可以很好的避免每次一回收会对整个新生代或老年代进行收集,导致停机场景。
优点:避免停机问题(Stop the World)

缺点:新的垃圾不断产生,会导致线程不断切换上下文,导致回收垃圾成本上升,导致系统吞吐量的下降;

分区收集算法
分区算法主要是通过将整个堆空间划分成连线不同的小区间,每一个区间都可以独立使用,独立回收。这样的话可以通过算法来控制每次对垃圾回收的是哪几个分区,不会因为每次一回收把某个大区都回收了,降低停机概率。

优点:避免停机和合理回收特定分区;缺点:算法较复杂,需要动态计算每次回收的分区;

相关工具如下:

分析:

小结:

springboot 整合 JVM类加载过程与双亲委派机制与类加载器与类字节码详解学习,请大家指正~

参考资料和推荐阅读

1.链接: 参考资料.

这篇关于JVM (标记-清除算法、复制算法、标记-整理算法、分代收集算法、分区算法)...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338336

相关文章

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语