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

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis