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 Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H